合併排序的思路是:把數組分紅兩部分,分別進行排序,再把排好序的兩部分合併成排序數組。合併排序對一個n個元素的數組排序所需時間是O(nlogn)。用合併排序排序{9, 4, 5, 2, 1, 7, 4, 6}過程以下:ios
算法C++實現:算法
1 //對n個數進行合併排序 2 void Merge(int A[], int low, int mid, int high) 3 { 4 int B[];//輔助數組 5 int s = low , t = mid + 1 , k = low; 6 7 //將小元素添加到輔助數組 8 while( s<=mid && t<=high ) 9 { 10 if(A[s]<=A[t]) 11 { 12 B[k] = A[s]; 13 s = s + 1; 14 } 15 else 16 { 17 B[k] = A[t]; 18 t = t + 1; 19 } 20 k = k + 1; 21 } 22 23 if(s == mid + 1) 24 { 25 //把A[t...high]中剩餘的元素複製到B數組 26 for(int i = k ; i <= high ; i++) 27 B[i] = A[t++]; 28 } 29 else 30 { 31 //把A[s...mid]中剩餘的元素複製到B數組 32 for(int i = k ; i <= high ; i++) 33 B[i] = A[s++]; 34 } 35 36 //把B數組複製到A數組 37 for(int j = low ; j <= high ; j++) 38 A[j] = B[j]; 39 } 40 41 void mergesort(int A[] , int low ,int high) 42 { 43 if(low < high) 44 { 45 //把數組分紅兩部分分別排序在合併 46 int mid = (low+high)/2; 47 mergesort(A , low , mid); 48 mergesort(A , mid+1 , high); 49 Merge(A , low , mid , high); 50 } 51 }
快速排序的思路是:經過Split算法劃分數組A[low…high],求得A[low]的位置w,使得小於或等於A[w]的元素所處位置爲A[low…w-1],大於或等於A[w]的元素的位置爲A[w+1…high],再對兩個劃分後的子數組遞歸排序。快速排序最好情形的時間複雜度爲O(nlogn),最壞的情形爲O(n*n),平均時間複雜度O(nlogn)。對數組{4, 6, 3, 1, 8, 7, 2, 5}排序過程以下:數組
算法C++實現以下:ide
1 QuickSortint Split(int A[], int low, int high) 2 { 3 int i = low; 4 int x = A[low]; 5 6 //從左往右掃描,圍繞x劃分數組 7 for(int j = low+1 ; j <= high ; j++) 8 { 9 if(A[j] <= x) 10 { 11 i++; 12 if(i != j) 13 { 14 A[0] = A[i]; 15 A[i] = A[j]; 16 A[j] = A[0]; 17 } 18 } 19 } 20 21 //A[low]填入i位置 22 A[0] = A[low]; 23 A[low] = A[i]; 24 A[i] = A[0]; 25 26 return i; 27 } 28 29 void quicksort(int A[], int low, int high) 30 { 31 int w; 32 if(low < high) 33 { 34 w = Split(A, low, high);//把數組劃分紅兩部分 35 quicksort(A, low, w-1);//對左半部分遞歸處理 36 quicksort(A, w+1, high);//對有半部分遞歸處理 37 } 38 }
隨機產生20組數據,第一組500000個,第二組1000000個,以此類推,到第20組10000000個,數據範圍爲(0,100000),對同一組數據進行合併排序和快速排序,記錄運行時間,程序以下:ui
1 #include <iostream> 2 #include <stdlib.h> 3 #include <time.h> 4 #include <string> 5 6 using namespace std; 7 8 int A[10000001];//數據數組 9 int C[10000001];//複製數組 10 int B[10000001];//輔助數組 11 12 //初始化,隨機產生n個數據保存在C數組中 13 void Initialize(int n) 14 { 15 srand((unsigned)time(0)); 16 for(int i = 1 ; i <= n ; i++) 17 C[i] = rand()%100000; 18 } 19 20 //複製C數組元素到A數組 21 void CopyCtoA(int n) 22 { 23 for(int i = 1 ; i <= n ; i++) 24 A[i] = C[i]; 25 } 26 27 28 //Merge 29 void Merge(int A[], int low, int mid, int high) 30 { 31 //int B[100001];//輔助數組 32 int s = low , t = mid + 1 , k = low; 33 34 //將小元素添加到輔助數組 35 while( s<=mid && t<=high ) 36 { 37 if(A[s]<=A[t]) 38 { 39 B[k] = A[s]; 40 s = s + 1; 41 } 42 else 43 { 44 B[k] = A[t]; 45 t = t + 1; 46 } 47 k = k + 1; 48 } 49 50 if(s == mid + 1) 51 { 52 //把A[t...high]中剩餘的元素複製到B數組 53 for(int i = k ; i <= high ; i++) 54 B[i] = A[t++]; 55 } 56 else 57 { 58 //把A[s...mid]中剩餘的元素複製到B數組 59 for(int i = k ; i <= high ; i++) 60 B[i] = A[s++]; 61 } 62 63 //把B數組複製到A數組 64 for(int j = low ; j <= high ; j++) 65 A[j] = B[j]; 66 } 67 68 //MergeSort 69 void MergeSort(int A[], int low, int high) 70 { 71 if(low < high) 72 { 73 //把數組分紅兩部分分別排序在合併 74 int mid = (low+high)/2; 75 MergeSort(A , low , mid); 76 MergeSort(A , mid+1 , high); 77 Merge(A , low , mid , high); 78 } 79 } 80 81 //Split 82 int Split(int A[],int low,int high) 83 { 84 A[0]=A[low]; //把基準記錄暫存在A[0]中 85 int key=A[low]; 86 while(low<high) 87 { 88 while((low<high)&&(A[high]>=key)) //從右到左掃描 89 high--; 90 if(low<high) //low>=high而退出的循環,不須要移動數據 91 A[low++]=A[high]; //記錄,並將low往右移動一個單位 92 while((low<high)&&(A[low]<=key)) //從左到右掃描 93 low++; 94 if(low<high) 95 A[high--]=A[low]; //記錄,並將up往左移動一個單位 96 } 97 A[low]=A[0]; //正確的位置填入基準位置 98 return low; //返回當前填入基準記錄的所在位置 99 } 100 101 //QuickSort 102 void QuickSort(int A[], int low, int high) 103 { 104 int mid; 105 if(low < high) 106 { 107 mid = Split(A, low, high);//把數組劃分紅兩部分 108 QuickSort(A, low, mid-1);//對左半部分遞歸處理 109 QuickSort(A, mid+1, high);//對有半部分遞歸處理 110 } 111 } 112 113 114 115 //對n個數執行合併排序或快速排序,計算輸出執行時間 116 void Sort_ExcutionTime(int n , string sort_type) 117 { 118 CopyCtoA(n); 119 clock_t start, end; 120 double totaltime; 121 122 if(sort_type == "MergeSort") 123 { 124 start = clock(); 125 MergeSort(A, 1, n); 126 end = clock(); 127 } 128 else if(sort_type == "QuickSort") 129 { 130 start = clock(); 131 QuickSort(A, 1, n); 132 end = clock(); 133 } 134 135 totaltime = (double)(end-start)/CLOCKS_PER_SEC*1000; 136 //totaltime = end-start; 137 cout<<sort_type<<" running time is: "<<totaltime<<" ms"<<'\n'; 138 } 139 140 //執行程序 141 void Excute() 142 { 143 for(int i = 1 ; i <= 20 ; i++) 144 { 145 Initialize(500000*i); 146 cout<<"n="<<500000*i<<'\n'; 147 Sort_ExcutionTime(500000*i, "MergeSort"); 148 Sort_ExcutionTime(500000*i, "QuickSort"); 149 cout<<'\n'; 150 } 151 } 152 153 int main() 154 { 155 Excute(); 156 return 0; 157 }
執行結果:
排序同一組數據,當數據量較少時,QuickSort的運行時間比MergeSort的運行時間少,隨着數據增長,MergeSort的運行時間比QuickSort的運行時間少。spa
code