自底向上的归并排序算法的优化
来源:3-4 自底向上的归并排序算法
宝慕林3490596
2017-03-04
老师,我发现优化后,还是自顶向下的归并排序快,是什么原因呢
我使用了模板类进行封装,自定义了一个testManyTimesSort来测试数组元素数量剩余num个的时候,调用插入排序后的总时间
我选择的num是16,因为经过测试,千万级别,百万级别这样的数量,16个确实是插入排序性能最优的
帮忙看下是什么原因自顶向下的归并排序快
代码如下
#pragma once #include <algorithm> template<typename T> class MergeSort { public: static void mergeSort(T arr[],int n,int num); static void mergeSortBU(T arr[], int n,int num); private: static void __mergeSort(T arr[],T aux[],int l,int r,int num); static void __merge(T arr[], T aux[],int l,int mid, int r); }; template<typename T> void MergeSort<T>::mergeSort(T arr[], int n,int num) { T *aux = new T[n]; __mergeSort(arr,aux,0,n-1,num); delete []aux; aux=NULL; } template<typename T> void MergeSort<T>::mergeSortBU(T arr[], int n,int num) { T *aux = new T[n]; for (int sz = 1;sz < n;sz += sz) { for (int i = 0;i+sz < n;i += sz + sz) { if (n <= 16) { insertionSort(arr, 0, n); } if (arr[i + sz - 1]>arr[i + sz]) { __merge(arr, aux, i, i + sz - 1, min(i + sz + sz - 1, n - 1)); } } } delete[]aux; aux = NULL; } template<typename T> void MergeSort<T>::__mergeSort(T arr[],T aux[], int l, int r,int num) { if (l >= r) { return; } if (r - l <= num) { insertionSort(arr,l,r); } int mid=(l+r)/2; __mergeSort(arr,aux,l,mid,num); //切 __mergeSort(arr,aux,mid+1,r,num); //并 if(arr[mid]>arr[mid+1]) { __merge(arr,aux,l,mid,r); //排序 } } template<typename T> void MergeSort<T>::__merge(T arr[],T aux[], int l, int mid, int r) { for (int i = l;i <= r;i++) { aux[i-l]=arr[i]; } int i=l,j=mid+1; for (int k = l;k <= r;k++) { if (i > mid) { arr[k]=aux[j-l]; j++; } else if(j>r) { arr[k]=aux[i-l]; i++; } else if (aux[i - l] < aux[j - l]) { arr[k] = aux[i-l]; i++; } else { arr[k]=aux[j-l]; j++; } } }
#pragma once #pragma warning(disable:4996) //#define _SCL_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <time.h> #include <ctime> #include <cassert> using namespace std; namespace SortTestHelper { int *generateRandomArray(int n, int rangeL, int rangeR) { assert(rangeL <= rangeR); int *arr=new int[n]; srand((unsigned)time(NULL)); for (int i = 0;i < n;i++) { arr[i]=rand() % (rangeR-rangeL+1)+rangeL; } return arr; } template<typename T> void printArray(T arr, int n) { for (int i = 0;i < n;i++) { cout << arr[i] << " "; } cout << endl; } template<typename T> void testsort(string sortName, void(*sort)(T[], int), T arr[], int n) { clock_t startTime = clock(); sort(arr,n); clock_t endTime = clock(); assert(isSorted(arr,n)); cout <<sortName<<":" << double(endTime-startTime)/CLOCKS_PER_SEC<<"s"<<endl; } template<typename T> void testManyTimesSort(string sortName, void(*sort)(T[], int,int), T arr[], int n,int num) { clock_t startTime = clock(); sort(arr, n,num); clock_t endTime = clock(); assert(isSorted(arr, n)); cout << sortName << ":" << double(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl; } template<typename T> bool isSorted(T arr[], int n) { for (int i = 0;i < n-1;i++) { if (arr[i] > arr[i+1]) { return false; } } return true; } int *copyIntArray(int a[], int n) { int *arr=new int[n]; copy(a,a+n,arr); return arr; } int *generateNearlyOrderedArray(int n, int swapTimes) { int *arr=new int[n]; for (int i = 0;i < n;i++) { arr[i]=i; } srand((unsigned)time(NULL)); for (int i = 0;i < swapTimes;i++) { int A=rand()%n; int B = rand() % n; swap(arr[A],arr[B]); } return arr; } }
#include <iostream> #include <string> #include <ctime> #include "InsertionSort.h" #include "SelectionSort.h" #include "SortTestHelper.h" //#include "MergeSort_maybe.h" #include "MergeSort.h" #include "MergeSort_Tercher.h" using namespace std; int main() { int n = 1000000; int swapTimes=100; while(true) { getchar(); int *arr = SortTestHelper::generateRandomArray(n, 0, n); int *arr2 = SortTestHelper::copyIntArray(arr, n); int *arr3 = SortTestHelper::generateNearlyOrderedArray(n, swapTimes); int *arr4 = SortTestHelper::generateNearlyOrderedArray(n, swapTimes); int *arr5 = SortTestHelper::copyIntArray(arr, n); //SortTestHelper::testsort("mergeSort", &MergeSort<int>::mergeSort, arr,n); //SortTestHelper::testsort("mergeSort", &MergeSort<int>::mergeSortBU, arr2, n); //SortTestHelper::testsort("mergeSort", mergeSort, arr2, n); //SortTestHelper::testsort("insertionSort", insertionSort, arr, n); //SortTestHelper::testsort("insertionSort", insertionSort, arr2, n); //SortTestHelper::testsort("insertionSort", insertionSort, arr4, n); //SortTestHelper::testsort("selectionSort", selectionSort, arr3, n); for(int i=16;i<200;i++) { for(int j=0;j<10;j++) { int *arr6 = SortTestHelper::copyIntArray(arr, n); int *arr7 = SortTestHelper::copyIntArray(arr, n); cout << i << "."; SortTestHelper::testManyTimesSort("mergeSort ", &MergeSort<int>::mergeSort, arr6, n,i); cout << i << "."; SortTestHelper::testManyTimesSort("mergeSortBU", &MergeSort<int>::mergeSortBU, arr7, n, i); cout << endl; delete []arr6; arr6 = NULL; delete[]arr7; arr7 = NULL; } } delete[]arr; arr = NULL; delete[]arr2; arr2 = NULL; delete[]arr3; arr3 = NULL; delete[]arr4; arr4 = NULL; delete[]arr5; arr5 = NULL; } }
写回答
1回答
-
宝慕林3490596
提问者
2017-03-04
改了活动解决方案配置,现在是Release模式,把数据量调成千万级别,可以明显看出mergeSortBU快一些,可能是Debug模式下min函数占用时间长吧,因为mergeSort是没有用min函数的
012017-03-04
相似问题