Merge SortΒΆ
Merge sort breaks the array into halves and merges them together.
- Check that the array has at least two elements
- Split up the array in halves
- Recursively repeat step 1 - 2 until you have at least two elements
- Merge the two halves.
2 6 5 1 4 3 Half 1: 2 6 5 Half 1.1: 2 Half 1.2: 6 5 Half 1.2.1: 6 Half 1.2.2: 5 Merge half 1.2.1 and 1.2.2 5 6 Merge half 1.1 and 1.2 2 5 6 Half 2: 1 4 3 Half 2.1: 1 Half 2.2: 4 3 Half 2.2.1: 4 Half 2.2.2: 3 Merge half 2.2.1 and 2.2.2 3 4 Merge half 2.1 and 2.2 1 3 4 Merge half 1 and 2 1 2 3 4 5 6
void mergeSort(int foo[], int n)
{
if (n <= 1)
return;
mergeSort(foo, n / 2);
mergeSort(foo + n / 2, n);
merge(foo, n / 2, n); // foo now sorted
}
void merge(int arr[], int n1, int n2)
{
int i = 0, j = 0, k = 0; // i is used for first half of inputted array, j for second half, k for temp array
int *temp = new int[n1 + n2]; // temporary array
int *first = array; // Pointer to beginning of first half
int *second = first + n1; // Pointer to beginning of second half
while (i < n1 || j < n2)
{
if (i == n1) // first reached the end of its half
temp[k++] = second[j++];
else if (j == n2) // second reached the end of its half
temp[k++] = first[i++];
else if (first[i] < second[j])
temp[k++] = first[i++]; // Copy the value of the smaller number into temp, then increment the variables
else // The second number must be smaller or equal to the first number
temp[k++] = second[j++];
}
for (i = 0; i < n1 + n2; i++)
arr[i] = temp[i]; // Override the contents of the original array with temp
delete [] temp;
}
The big-o is always O(nlog(n)). Why? The mergeSort function always breaks the array in half log(n) times, and the merge function merges n items every time.
void mergeSort(int foo[], int n)
{
if (n <= 1)
return;
mergeSort(foo, n / 2); // O(log(n))
mergeSort(foo + n / 2, n); // O(log(n))
merge(foo, n / 2, n); // O(n)
} // O(nlog(n))
void merge(int arr[], int n1, int n2)
{
int i = 0, j = 0, k = 0;
int *temp = new int[n1 + n2];
int *first = array;
int *second = first + n1;
while (i < n1 || j < n2) O(n)
{
if (i == n1)
temp[k++] = second[j++];
else if (j == n2)
temp[k++] = first[i++];
else if (first[i] < second[j]) // ** Should this be <= instead?
temp[k++] = first[i++];
else
temp[k++] = second[j++];
}
for (i = 0; i < n1 + n2; i++) O(n)
arr[i] = temp[i];
delete [] temp;
} O(n) (f(n) = n + n = 2n)
The merge sort is stable.
2(a) 2(b) 1 Half 1: 2(a) Half 2: 2(b) 1 Half 2.1: 2(b) Half 2.2: 1 Merge 2.1 and 2.2 1 2(b) Merge 1 and 2 2(a) 1 2(b) n1 = 1 n2 = 2 i = 0 (2(a)) index(value) j = 0 (1) first[0] > second[0], copy 1 temp = 1 j = 1 (2(b)) first[0] == second[1], copy 2(b) ** Is this a mistake? Wikipedia says that mergesort is stable most of the time, is this an exception or is there a mistake? temp = 1 2(b) j = 2 (?) j == n2, copy 2(a) temp = 1 2(b) 2(a) arr = 1 2(b) 2(a)