The selection sort, insert sort, bubble sort, etc. are all very simple and basic sorting algorithms, all using two for loop, time complexity is square level. This article introduces an algorithm that is slightly more complex than before: merge sort. Merge sorting algorithm inside the merging idea and recursive method is worth learning, the process of merging is often accompanied by recursion, many other places will use these two methods, such as the previous "sword refers to offer topic series three" in the 12th question "Merge two sort of linked list" on the use of these two ways of thinking.
the process of merging
For two independent arrays, it is the merging of two ordered arrays into an array, so that the merged array remains orderly. For an array, it can be divided into two parts first, the parts are ordered, and then merged into an ordered array. When you do this, you define two pointers, each pointing to elements in two arrays, to iterate through the array, and then create a new array to store the merged elements.
In merge sort, assume that p, Q, and mid point to the first element of the array arr[], the last element, the index position of the intermediate element, divide the array arr[] into two halves: Arr[p~mid], Arr[mid+1~q], and then merge the elements in the two sub-arrays. You can also divide two sub-arrays into smaller sub-arrays, merging smaller sub-arrays ... And so on, until the subarray is 1 long and then merge in turn. When merging, there are 4 criteria: if the left half of the element is traversed, the right half of the remaining elements are placed directly into the array, and if the right half of the elements are traversed, the left half of the remaining elements are placed directly into the array; If the left half of the current element is smaller than the right half of the current element, the The right half of the current element is placed in an array.
The following is an example of an array of length 8, which illustrates the specific process of merging. Set the original array to int arr[] = {1,3,5,7,2,4,6,8}, create a new auxiliary array aux[] to temporarily store the elements in the array, first copy the elements in the original array into the auxiliary array, and then put the merged results back into the original array. The initial I, J, respectively, points to the first element of the auxiliary array, the second half of the molecular array, and then slowly moves through the two arrays. The red element represents the position of the elements of the two sub-arrays that each trip I, j two pointers point to, the gray elements represent the elements that have been traversed, and the black bold elements represent elements that have not been traversed.
The code for the merge process:
Public Static voidMergeint[] arr,int[] aux,intPintMidintq) { for(intk=p;k<=q;k++) {//Copy to the secondary array firstAUX[K] =Arr[k]; } inti=p,j=mid+1;//I, J points to the left and right half pointers of the auxiliary array, starting from the starting position for(intk=p;k<=q;k++) {//k points to the original array arr[], according to I, J pointer position to determine whether the left and right half of the block is traversed if(i > Mid) arr[k] = aux[j++];//left half of the block traversed Else if(j>q) Arr[k] = aux[i++];//right half of the block traversed Else if(Aux[j]>aux[i]) arr[k] = aux[i++]; ElseArr[k] = aux[j++]; } }
Here are two ways to sort recursively: top-down merge sort and bottom-up merge sort, both of which use the merge code above.
top to bottom merge
Top-down merging is a recursive method of merging, and it is also a typical use of "divide and conquer thought" in algorithm design. It divides a big problem into small problems, solves small problems, and then solves the big problem with the answers to all the small questions. If you can sort two sub-arrays, you can sort the entire array by merging the two sub-arrays. Top-down merging sorts the left half of the array first, then sorts the right half, and then sorts the entire array by merging the left and next parts. The detailed procedure is shown in the following code comment.
Merge full code from top down:
//Merge Sort (recursive recursion, top-down) Public Static voidSortint[] arr) {//This method executes only once, and the following two methods execute multiple times if(arr = =NULL)return; int[] aux =New int[Arr.length];//Auxiliary ArraysSort (arr,aux,0,arr.length-1); } Public Static voidSortint[] arr,int[] aux,intPintq) { if(P>=Q)return; intMid = (p+q) >>1; Sort (arr,aux,p,mid); //Merge left half blockSort (arr,aux,mid+1,q);//Right half block mergeMerge (ARR,AUX,P,MID,Q);//Merge Detailed Process } Public Static voidMergeint[] arr,int[] aux,intPintMidintq) { for(intk=p;k<=q;k++) {//Copy to the secondary array firstAUX[K] =Arr[k]; } inti=p,j=mid+1;//I, J points to the left and right half pointers of the auxiliary array, starting from the starting position for(intk=p;k<=q;k++) {//k points to the original array arr[], according to I, J pointer position to determine whether the left and right half of the block is traversed if(i > Mid) arr[k] = aux[j++];//left half of the block traversed Else if(j>q) Arr[k] = aux[i++];//right half of the block traversed Else if(Aux[j]>aux[i]) arr[k] = aux[i++]; ElseArr[k] = aux[j++]; } }
merge from bottom up
Top-to-bottom merging is a recursive method of merging, which is useful when solving large array sorting problems. In fact, most of the times we encounter are decimal groups, so the bottom-up merge is to merge the tiny arrays, then merge the decimal groups into pairs, and so on, until the entire array is merged together. The first thing we do is 22 merge, then 44 merge, then 88 merge, go on. The second sub-array of the last merge of each trip may be less than the length of the first Subarray, and the remaining two sub-array lengths should be equal, doubling the length of each sub-array. The detailed procedure is shown in the following code comment.
To merge the full code from bottom up:
//non-recursive mode Public Static voidSortnotrecursion (int[] arr) { if(arr = =NULL)return; int[] aux =New int[Arr.length]; for(inti=1;i<arr.length;i*=2) {//P-q+1=2*i: That is, the sub-array length is 2*i,i as the subarray half length, each trip I doubles for(intJ=0;J<ARR.LENGTH-I;J+=I*2) {//J: Sub-array start position intp = j;//Sub-array header pointer intQ = math.min (j+i*2-1,arr.length-1);//sub-array tail pointers, whichever is the minimum because the last sub-array length of each trip may be less than 2*i, the value of the last position pointer j+i*2-1 may exceed the maximum index of the array, at which time the maximum index is taken arr.length-1 intMID = J+i-1;//Middle position. Note that you cannot use (P+Q) >>1 because the last sub-array length of each trip may be less than the 2*i,q position may be arr.length-1. Merge (ARR,AUX,P,MID,Q);//The last sub-array of each trip is only a merge operation if the length is greater than I, less than or equal to I is not carried out, controlled by J<arr.length-i } } } Public Static voidMergeint[] arr,int[] aux,intPintMidintq) { for(intk=p;k<=q;k++) {//Copy to the secondary array firstAUX[K] =Arr[k]; } inti=p,j=mid+1;//I, J points to the left and right half pointers of the auxiliary array, starting from the starting position for(intk=p;k<=q;k++) {//k points to the original array arr[], according to I, J pointer position to determine whether the left and right half of the block is traversed if(i > Mid) arr[k] = aux[j++];//left half of the block traversed Else if(j>q) Arr[k] = aux[i++];//right half of the block traversed Else if(Aux[j]>aux[i]) arr[k] = aux[i++]; ElseArr[k] = aux[j++]; } }
Merge sort is a stable sorting algorithm, but it is not in-situ merging, but requires an auxiliary array. The time complexity of the merge sort is O (nlogn) and the spatial complexity is O (n).
Reprint please specify the source http://www.cnblogs.com/Y-oung/p/8964964.html
To work, study, communicate or have any questions, please contact email: [Email protected]
Sorting algorithm merging and sorting