归并排序:
#include <iostream> #include "SortTestHelper.h" #include "InsertionSort.h" using namespace std; // 将arr[l...mid]和arr[mid+1...r]两部分进行归并 template<typename T> void __merge(T arr[], int l, int mid, int r) { // 经测试,传递aux数组的性能效果并不好 T aux[r - l + 1]; 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++; } } } // 递归使用归并排序,对arr[l...r]的范围进行排序 template<typename T> void __mergeSort(T arr[], int l, int r) { if (l >= r) return; int mid = (l + r) / 2; __mergeSort(arr, l, mid); __mergeSort(arr, mid + 1, r); __merge(arr, l, mid, r); } template<typename T> void mergeSort(T arr[], int n) { __mergeSort(arr, 0, n - 1); }
int main() { int n = 50000; // 测试1 一般性测试 cout<<"Test for Random Array, size = "<<n<<", random range [0, "<<n<<"]"<<endl; int* arr1 = SortTestHelper::generateRandomArray(n,0,n); int* arr2 = SortTestHelper::copyIntArray(arr1, n); SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n); SortTestHelper::testSort("Merge Sort", mergeSort, arr2, n); delete[] arr1; delete[] arr2; cout<<endl; Test for Random Array, size = 50000, random range [0, 50000] Insertion Sort : 3.173 s Merge Sort : 0.012 s // 测试2 测试近乎有序的数组 int swapTimes = 100; cout<<"Test for Random Nearly Ordered Array, size = "<<n<<", swap time = "<<swapTimes<<endl; arr1 = SortTestHelper::generateNearlyOrderedArray(n,swapTimes); arr2 = SortTestHelper::copyIntArray(arr1, n); SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n); SortTestHelper::testSort("Merge Sort", mergeSort, arr2, n); delete(arr1); delete(arr2); Test for Random Nearly Ordered Array, size = 50000, swap time = 100 Insertion Sort : 0.008 s Merge Sort : 0.008 s return 0; }
归并排序优化:
// 递归使用归并排序,对arr[l...r]的范围进行排序 template<typename T> void __mergeSort2(T arr[], int l, int r){ // 对于小规模数组,使用插入排序 if( r - l <= 15 ){ insertionSort(arr, l, r); return; } int mid = (l+r)/2; __mergeSort2(arr, l, mid); __mergeSort2(arr, mid+1, r); // 对于arr[mid] <= arr[mid+1]的情况,不进行merge // 对于近乎有序的数组非常有效,但是对于一般情况,有一定的性能损失 if( arr[mid] > arr[mid+1] ) __merge(arr, l, mid, r); } template<typename T> void mergeSort2(T arr[], int n){ __mergeSort2( arr , 0 , n-1 ); }
优化后的测试:
int main() { int n = 50000; // 测试1 一般性测试 cout<<"Test for Random Array, size = "<<n<<", random range [0, "<<n<<"]"<<endl; int* arr1 = SortTestHelper::generateRandomArray(n,0,n); int* arr2 = SortTestHelper::copyIntArray(arr1, n); int* arr3 = SortTestHelper::copyIntArray(arr1, n); SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n); SortTestHelper::testSort("Merge Sort", mergeSort, arr2, n); SortTestHelper::testSort("Merge Sort 2", mergeSort2, arr3, n);
Test for Random Array, size = 50000, random range [0, 50000]
Insertion Sort : 3.181 s
Merge Sort : 0.012 s
Merge Sort 2 : 0.011 s
delete[] arr1; delete[] arr2; delete[] arr3; cout<<endl; // 测试2 测试近乎有序的数组 int swapTimes = 10; cout<<"Test for Random Nearly Ordered Array, size = "<<n<<", swap time = "<<swapTimes<<endl; arr1 = SortTestHelper::generateNearlyOrderedArray(n,swapTimes); arr2 = SortTestHelper::copyIntArray(arr1, n); arr3 = SortTestHelper::copyIntArray(arr1, n); SortTestHelper::testSort("Insertion Sort", insertionSort, arr1, n); SortTestHelper::testSort("Merge Sort", mergeSort, arr2, n); SortTestHelper::testSort("Merge Sort 2", mergeSort2, arr3, n);
Test for Random Nearly Ordered Array, size = 50000, swap time = 10
Insertion Sort : 0.001 s
Merge Sort : 0.007 s
Merge Sort 2 : 0.002 s
delete[] arr1; delete[] arr2; delete[] arr3; return 0; }