Many online merging and sorting articles focus on the principle of merging and sorting, but they don't pay much attention to the code implementation, so let's take a look at the code implementation of merging algorithm in this chapter.
principle
To learn an algorithm, you must first learn its principle~
Merge sort, using the idea of divide and conquer, first divide the array into half groups until there is only one element in each group, then sort and merge the array, and finally turn it into a completely ordered array.
In the last animation demonstration, the dynamic diagram of the up main of "five minute learning algorithm" is quoted here. I think it's good
Although the animation demonstration is grouped at the same time, when you debug the code, you will find that it is divided into one side first and then the other side
There is also a picture that I think is quite good, which well reflects the idea of divide and conquer.
code implementation
Let's first look at the implementation of the merge section
void merge(int low,int mid,int high) { int left = low; //Array pointer in the left part int right = mid + 1; //Right part pointer int k = low; //Pointer to the temp array while (left < mid + 1 && right < high + 1) { /*This while is used to combine two arrays into a new one Array, which is temporarily stored in temp []*/ if (nums[left] > nums[right]) { temp[k++] = nums[right++]; //k + + and right + + here mean to assign values first and then add 1 } //It's equivalent to the following else else { temp[k] = nums[left]; k++; left++; } } //Check whether the left sequence is empty while (left < mid + 1) { /*These two while are used to store the values of one array and leave the other array The elements are stored in sequence*/ temp[k++] = nums[left++]; } //Check whether the sequence on the right is empty while (right < high + 1) { temp[k++] = nums[right++]; } //Move back to the original array. num[i] is the array defined in the global area to be sorted for (int i = low; i <= high; i++) { //i=low here. It can't be equal to 0 nums[i] = temp[i]; } }
Code implementation of the mergeSort part
void mergeSort(int low,int high) //Use recursion { if(low >= high) { //It is equivalent to a group of single elements. Just return it directly return; } int mid = low + ((high - low) >> 1);/*Prevent low and high from crossing the boundary. 1 is the same as dividing by 2, but Faster than / 1 efficiency*/ //branch mergeSort(low, mid); //First on the left mergeSort(mid + 1, high); //Finish left and right //cure merge(low, mid, high); //Merge layer by layer, and small arrays are gradually merged into large arrays }
Finally, let's take a look at the complete specific code
#include <iostream> using namespace std; int nums[7] = { 7,3,5,2,9,8 };//Array to be sorted int temp[7];//Temporary storage array void merge(int low,int mid,int high) { int left = low; //Array pointer in the left part int right = mid + 1; //Right part pointer int k = low; //Pointer to the temp array while (left < mid + 1 && right < high + 1) { if (nums[left] > nums[right]) { temp[k++] = nums[right++]; } else { temp[k] = nums[left]; k++; left++; } } //Check whether the left sequence is empty while (left < mid + 1) { temp[k++] = nums[left++]; } //Check whether the sequence on the right is empty while (right < high + 1) { temp[k++] = nums[right++]; } //Move back to the original array for (int i = low; i <= high; i++) { //i=low here. It can't be equal to 0 nums[i] = temp[i]; } } void mergeSort(int low,int high) { if(low >= high) { return; } int mid = low + ((high - low) >> 1);//To prevent low and high from crossing the boundary, 1 is the same as dividing by 2, but it is faster than / 2 //branch mergeSort(low, mid); mergeSort(mid + 1, high); //cure merge(low, mid, high); } int main() { mergeSort(0, 5); for (int i = 0; i <=5; i++) { cout << nums[i] << " "; } cout << endl; return 0; }
It is better to debug the code and see the change of variable value, which will make the implementation of merging algorithm more clear.
Complexity analysis
-
Time complexity:
From this recursive tree, we can see that the time cost of the first layer is cn, the time cost of the second layer is cn/2+cn/2=cn... The cost of each layer is cn, and there are a total of logn+1 layers, so the total time cost is cn*(logn+1). The time complexity is O(nlogn) -
Space complexity: the merge sort algorithm requires an additional sequence temp [] to store the sorted results. The space occupied is n, so the space complexity is O(n)
-
Stability: in the worst, best and average cases, the time complexity of merging and sorting is O(nlogn). It can be seen from the merging process that the merging and sorting is stable.
Summary:
Merge sort algorithm is efficient, because its time complexity is only O(nlogn), so when there is a large amount of data, merge sort is a good choice. For C friends who don't know much about the divide and conquer idea in the algorithm, you can check the concept first, and then understand the code implementation with the help of debugging.