Data structure algorithm learning summary - MOOC (8) Merge sort (bottom-up, from small to large)
1. Review
In the previous section, we talked about the optimization of top-down recursive merge sort. We can merge from bottom to top without using recursion.
2. Actual combat
main.cpp
#include <iostream> #include "SortTestHelper.h" #include "MergeSort.h" #include "InsertSort.h" using namespace std; /** * Bottom-up merge */ template<typename T> void mergeSortBU(T arr[],int n){ for (int sz = 1; sz <= n; sz + = sz) { for(int i = 0;i + sz < n;i+=sz+sz){ //Optimization 1, insertion sort for nearly ordered arrays if(i >= i+sz+sz-1-15){ insertSort(arr,i,i+sz+sz-1); } //Optimize 2, like 2 3|4 5, the left and right are ordered, 3 is smaller than 4, then the entire array is from small to large, no need to sort if(arr[i+sz-1] > arr[i+sz-1+1]){ __merge (arr, i, i + sz-1, min (i + sz + sz-1, n-1)); } } } } int main(){ int n = 100000; int* arr = SortTestHelper::generateNearlyOrderedArray(n,100); int* arr1 = SortTestHelper::copyArray(arr,n); SortTestHelper::testSort("Merge Sort BU:",mergeSortBU,arr,n); SortTestHelper::testSort("Merge Sort:",mergeSort,arr1,n); delete[] arr; return 0; }
MergeSort.h
#ifndef MERGESORT_H_ #define MERGESORT_H_ #include <iostream> #include "InsertSort.h" /** * Merge the two parts [l...mid] and [mid+1...r] */ template<typename T> void __merge(T arr[],int l,int mid,int r){ //Temporary space, store the array of arr T aux[r-1+1]; for(int i = l;i<=r;i++) aux [il] = arr [i]; int i = l,j=mid+1; for(int k = l;k<=r;k++){ //i>mid means that the array where i is located has been merged, and the array where j is located has not been merged, and needs to be merged again if(i > mid){ arr[k] = aux[jl]; j++; }else if(j > r){//j>r indicates that the array where j is located has been merged, and the array where i is located has not been merged, and needs to be merged again arr [k] = aux [il]; i++; }else if(aux[il]<aux[jl]){ arr [k] = aux [il]; i++; }else{ arr[k] = aux[jl]; j++; } } } /** * Recursively use merge sort to sort the range of arr[l...r] */ template<typename T> void __mergeSort(T arr[],int l,int r){ // if(l >= r) // return; //Optimize 2 if(l >= r-15){ insertSort(arr,l,r); return; } int mid = (l+r)/2; __mergeSort(arr,l,mid); __mergeSort(arr,mid+1,r); //Optimize 1 if(arr[mid] > arr[mid+1]){ __merge(arr,l,mid,r); } } template<typename T> void mergeSort(T arr[],int n){ __mergeSort(arr,0,n-1); } #endif
operation result
Merge Sort BU:: 0.007sMerge Sort: : 0.005s
Summarize
Bottom-up merging is similar to top-down merging. Strictly speaking, top-down efficiency is better.
One advantage of bottom-up merging is that it can sort the linked list. Interested students can study it by themselves.
Comments and Suggestions
If you have any questions or suggestions, please leave a message to discuss