Origin: von noriman was first implemented on edvac.
Basic Idea:
- Divide an array into (divide array into two halves)
- Recursive sorting of each part (recursively sort each half)
- Merge two parts (merge two halves)
Merging and sorting reflects the idea of division and governance (divide and conquer)
Demo:
1. Given the original array a [], the sub-arrays from Lo to mid, Mid + 1 to Hi of this array are sorted separately.
2. Copy the array to the auxiliary array (auiiary array), subscripts I and j For the first element of the two parts, respectively, and subscripts K for the first element of the original array
3. Compare the subscripts of I and J, assign a smaller value to the element at the position of K subscripts, and then increment the subscripts of K and value assignment;
In this demonstration, the element of the J subject is relatively small, so a is assigned to the K position, and then increments K and J, that is, J + 1, k + 1
4. Repeat the above process until the comparison is complete.
Implementation in Java
Public class merge {Private Static void Merge (comparable [] A, comparable [] aux, int Lo, int mid, int hi) {assert issorted (A, lo, mid ); // check a [lo .. mid] whether to order assert issorted (A, Mid + 1, hi); // check a [Mid + 1 .. hi] whether to order for (int K = lo; k <= Hi; k ++) // copy the array aux [k] = A [k]; int I = Lo, j = Mid + 1; for (int K = lo; k <= Hi; k ++) {if (I> mid) A [k] = aux [J ++]; else if (j> Hi) A [k] = aux [I ++]; else if (less (Aux [J], aux [I]) A [k] = aux [J ++]; else a [k] = aux [I ++];} assert issorted (A, lo, hi);} Private Static void sort (comparable [] A, comparable [] aux, int low, int hi) {If (Hi <= LO) return; int mid = lo + (Hi-Lo)/2; sort (A, aux, lo, mid ); sort (A, aux, Mid + 1, hi); merge (A, aux, lo, mid, hi);} public static void sort (comparable []) {aux = new comparable [. length]; sort (A, aux, 0,. length-1 );}}
Note: assert function: checks the value in the expression. If it is true, the program runs normally. If it is false, an exception is thrown to terminate the operation.
Performance analysis:
The algorithm complexity is N * log (n)
Optimization:
Problem: Additional memory needs to be opened based on array size N for Merge Sorting
In-Place algorithm (in-place algorithm): an algorithm that occupies less space than or equal to C log (n.
Insert sorting, select sorting, and Hill sorting are all in-situ algorithms. Merge Sorting is not an in-situ algorithm. Wiki reference
Kronrod found in-place merge in 1969, but it does not seem so useful (challenge for the bored)
Practical improvements)
Improvement 1: Use Insert sorting for small arrays
- Merging and sorting requires a lot of overhead for opening up small sub-arrays (opening up arrays not only occupies memory for elements, but also has fixed overhead for the array itself)
- When the sub-array size exceeds 7, stop (cutoff) Using Insert sort
private static void sort(Comparable[] a, Comparable[] aux, int low, int hi){ if (hi <= lo + CUTOFF - 1) { Insertion.sort(a, lo, hi); return; } int mid = lo + (hi - lo) / 2; sort(a, aux, lo, mid); sort(a, aux, mid + 1, hi); merge(a, aux, lo, mid, hi);}
Improvement 2: When the array is sorted properly, the computation is stopped.
- After the two parts have been sorted, if the last element in the first half is greater than the first element in the second half, the whole sequence is ordered.
private static void sort(Comparable[] a, Comparable[] aux, int low, int hi){ if (hi <= lo) return; int mid = lo + (hi - lo) / 2; sort(a, aux, lo, mid); sort(a, aux, mid + 1, hi); if (!less(a[mid + 1], a[mid])) return; merge(a, aux, lo, mid, hi);}
Princeton University algorithm course algorithm part I mergesort Merge Sorting