So I'm trying to implement a Merge-Insertion sort in C++, where the recursive Merge method will be used until the segment length is less than 7, at which point an insertion sort will be used on that segment. My current code is as follows:
#include <iostream>
#include <stdlib.h>
using namespace std;
void print_array(double arr[], int arrLength) {
int timesToIterate;
if (arrLength < 25) {
timesToIterate = 1;
} else {
timesToIterate = arrLength/25;
}
for (int i = 0; i < timesToIterate; i++) {
int initialPosition = 25*i;
int endPosition;
if (timesToIterate == 1) {
endPosition = arrLength%25;
} else {
endPosition = initialPosition+25;
}
cout << "[" << initialPosition << "-" << initialPosition+24 << "]:";
for (int q = initialPosition; q < endPosition; q++) {
cout << " " << arr[q];
}
cout << endl << endl;
}
}
void insertion_sort(double arr[], int left, int right) {
int i, key, j;
for (i = left+1; i < right; i++) {
key = arr[i];
j = i-1;
while (j >= left && arr[j] > key) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}
void merge(double arr[], int left, int middle, int right) {
int i, j, k;
//declaration and filling of left and right arrays
double leftArray[middle-left+1], rightArray[right-middle];
for (i=0; i < middle-left+1; i++) { leftArray[i] = arr[left+i]; }
for (i=0; i < right-middle; i++) { rightArray[i] = arr[middle+1+i]; }
//merge two temp arrays into arr while sorting
i = 0; j = 0; k = left;
while (i < middle-left+1 && j < right-middle) {
if (leftArray[i] <= rightArray[j]) {
arr[k] = leftArray[i]; i++;
} else {
arr[k] = rightArray[j]; j++;
}
k++;
}
//loops to add extra element in left or right array
while (i < middle-left+1) {
arr[k] = leftArray[i]; i++; k++;
}
while (j < right-middle) {
arr[k] = rightArray[j]; j++; k++;
}
}
void merge_sort(double arr[], int left, int right) {
//base case for if arr is of length 1
if (right == left) {
return;
}
int middle = (left+right)/2;
//use merge sort for segments greater than 6, insertion sort for other
if (middle-left > 6) {
merge_sort(arr, left, middle);
} else {
insertion_sort(arr, left, middle);
}
if (right-middle+1 > 6) {
merge_sort(arr, middle+1, right);
} else {
insertion_sort(arr,middle+1, right);
}
//merge two segments together, regardless if sorted by merge or insertion
merge(arr, left, middle, right);
}
int main() {
int arrLength = 500;
//creation of array of length 500 with random doubles
double arr[arrLength];
for (int i = 0; i < arrLength; i++) {
arr[i] = (((double)(rand() % 20000)) / 10) - 1000;
}
//printing of initial array
cout << "Initial Array:" << endl;
print_array(arr, arrLength);
//printing of array after sorting
merge_sort(arr, 0, arrLength-1);
cout << endl << endl << "Sorted Array:" << endl;
print_array(arr, arrLength);
return 0;
}
I know for certain that my merge sort function works, and I'm fairly sure that my insertion sort works (although it hasn't been tested separately), but my output is not sorted as it should be. I believe the issue I'm having is in the left and right variables passed for merge sort vs insertion sort, where I'm accidentally overlapping on segments, but I don't know what ranges to pass to insertion sort.
I'm also curious as to if this type of sort can be considered viable to use from a time complexity and memory standpoint. Does implementing insertion sort into merge sort realistically impact the memory that merge sort uses, and if it does at the cost of what kind of time?