经典的排序算法
来源:互联网 发布:班服制作软件 编辑:程序博客网 时间:2024/06/05 01:50
一、归并排序
将两个和两个以上的排序表合成一个新的有序表,归并排序是分治法思想运用的一个典范。
1:简要过程:
将有 n个对象的原始序 列看作 n个有序子列,每个序列的长度为1,从第一个子序列开始,把相邻的子序列两两合并得到[n/2]个长度为2或者是1的归并项,(如果n为奇数,则最后一个有序子序列的长度为1),称这一个过程为一趟归并排序。
然后重复上述过程指导得到一个长度为n的序列为止。
2:排序效率:
一趟归并排序的操作是:调用[n/2b]次算法,整个过程需要[log2n]趟,课件归并排序时间复杂度是O(logn)
3:排序过程图:
4:具体算法实现:
1 //归并排序合并函数 2 void mergeSoft(int a[], int first, int mid, int last, int temp[]){ 3 int i = first, j = mid + 1; 4 int m = mid, n = last; 5 int k = 0; 6 while (i <= m && j <= n){ 7 if (a[i] <= a[j]){ 8 temp[k++] = a[i++]; 9 }else{10 temp[k++] = a[j++]; 11 }12 } 13 while (i <= m){14 temp[k++] = a[i++]; 15 }16 while (j <= n){17 temp[k++] = a[j++]; 18 } 19 20 for (i = 0; i < k; i++){21 a[first + i] = temp[i]; 22 } 23 } 24 25 //归并排序递归拆分函数26 void mergerSelf(int arr[], int left, int right, int arrTmp[]){27 if(left < right){28 int center = (left + right)/2;29 mergerSelf(arr, left, center, arrTmp);30 mergerSelf(arr, center+1, right, arrTmp);31 mergeSoft(arr, left, center, right, arrTmp);32 }33 } 34 //归并排序 35 void merger(int arr[], int n){36 int *arrTmp = new int[n];37 mergerSelf(arr, 0, n - 1, arrTmp);38 delete[] arrTmp;39 }
二、快速排序
快速排序是一种交换排序,说白了就是一种对起泡排序的改进,不过改进了不少,快速排序被认为是最好的一种排序算法(同量级别)。
1:简要过程:
选择一个基准元素,我们称之为中枢,通常选择第一个元素或者最后一个元素,中枢的选择很重要,直接影响排序的性能,这是因为如果代排序列有序,快速排序就退化为冒泡排序。将序列分割成左右两个序列。其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。一趟排序的具体做法将两个附设指针left和right,然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
2:排序效率:
在所有同级别的排序算法中其平均性能最好O(nlogn)。如果代排序列有序,快速排序就退化为冒泡排序,效率及其低下,这个可以在下面的效率比拼图中体现出来逆序的时候快速排序非常慢,效率很低下。所以可以在中枢的选择上优化可以选着最左边和最右边中间的元素取其平均值即可。
3:排序过程图:
4:具体算法实现:
1 //快速排序的元素移动 2 int fastSort(int arr[], int left, int right){ 3 int center = (left+right)/2; 4 int num = arr[center]; //记录中枢点的位置,这里选择最左边点当做中枢点 5 while(left < right){ 6 //比枢纽小的移动到左边 7 while(left < right && arr[right] >= num){ 8 right--; //一直到有一个元素小于所选关键中枢为止 9 }10 arr[left] = arr[right];11 12 while(left < right && arr[left] <= num){13 left++; //一直到有一个元素大于所选关键中枢为止 14 }15 arr[right] = arr[left]; //关键字入列 16 }17 arr[left] = num;18 return left; 19 } 20 21 //快速排序递归划分22 int fastSortSelf(int arr[], int left, int right){23 if(left < right){24 int lowLocation = fastSort(arr,left,right); //第一个指针的位置 25 fastSortSelf(arr,left,lowLocation - 1); 26 fastSortSelf(arr,lowLocation + 1,right);27 }28 } 29 30 //快速排序 31 void fast(int arr[], int n){32 fastSortSelf(arr,0,n-1);33 //记录时间34 }
各种算法效率比拼
下面是我自己写的一个算法比拼,测试数据有100-50000都有,分为最坏情况(逆序->正序)和随机情况(随机->正序),测试数据会因为机器的不同而不同,我的是win8,64, 4G,cpu2.5,欢迎大家测试
说明两点:要注意时间的得到方法,需要引入的头文件包括
1 #include <iostream>2 #include <iomanip> 3 #include <stdlib.h>4 #include <time.h>
1 end_time = clock(); 2 程序。。。。3 times = static_cast<double>(end_timestart_time)/CLOCKS_PER_SEC*1000;cout <<right ; cout <<setw(7) <<times<<"ms";
下面是程序代码:
1 #include <iostream> 2 #include <iomanip> 3 #include <stdlib.h> 4 #include <time.h> 5 using namespace std; 6 7 clock_t start_time, end_time; 8 int times; 9 10 void printfArr(int arr[], int n){ 11 for(int i = 0; i < n; i++){ 12 cout<<arr[i]<<" "; 13 } 14 } 15 16 //冒泡排序 17 void bubbling(int arr[], int n){ 18 start_time = clock(); 19 int i, j, temp; 20 for (j = 0; j < n - 1; j++){ 21 for (i = 0; i < n - 1 - j; i++){ 22 if(arr[i] > arr[i + 1]){ 23 temp = arr[i]; 24 arr[i] = arr[i + 1]; 25 arr[i + 1] = temp; 26 } 27 } 28 } 29 end_time = clock(); 30 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000; 31 cout <<right ; cout <<setw(7) <<times<<"ms"; 32 } 33 34 //直接选择排序 35 void directDialing(int arr[], int n){ 36 start_time = clock(); 37 int i,j,k,num; 38 for(i = 0; i < n; i++){ 39 num = 0; 40 for(j = 0; j < n-i; j++){ 41 if(arr[j] > arr[num]){ 42 num = j; 43 } 44 } 45 k = arr[n-i-1]; 46 arr[n-i-1] = arr[num]; 47 arr[num] = k; 48 } 49 end_time = clock(); 50 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000; 51 cout <<right ; cout <<setw(7) <<times<<"ms"; 52 } 53 54 //直接插入排序 (On2) 55 void insert(int arr[], int n){ 56 start_time = clock(); 57 int m,i,k; 58 for(i = 1; i < n; i++){ 59 m = arr[i]; 60 for(k = i-1; k >= 0; k--){ 61 if(arr[k] > m){ 62 arr[k+1] = arr[k]; 63 }else{ 64 break; 65 } 66 } 67 arr[k+1] = m; 68 } 69 end_time = clock(); 70 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000; 71 cout <<right ; cout <<setw(7) <<times<<"ms"; 72 } 73 74 //希尔排序 75 void Heer(int arr[], int n){ 76 start_time = clock(); 77 int i,j,k,num; 78 k = n/2; 79 while(k > 0){ 80 for(i = k; i < n; i++){ 81 num = arr[i]; 82 for(j = i - k;j >= 0; j -= k){ 83 if(arr[j] > num){ 84 arr[j+k] = arr[j]; 85 }else{ 86 break; 87 } 88 } 89 arr[j+k] = num; 90 } 91 k = k/2; 92 } 93 end_time = clock(); 94 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000; 95 cout <<right ; cout <<setw(7) <<times<<"ms"; 96 } 97 98 //堆调整 99 void adjust(int arr[], int n, int length){100 int max,b;101 while(n * 2 +1 <= length){//说明存在左节点 102 max = n * 2 + 1;103 if(n * 2 + 2 <= length){//说明存在右节点 104 if(arr[max] < arr[n * 2 + 2]){105 max = n * 2 + 2; //跟新最小的值 106 } 107 } 108 if(arr[n] > arr[max]){109 break;//顺序正确,不需要再调整 110 }else{111 b = arr[n];112 arr[n] = arr[max];113 arr[max] = b;114 n = max;115 }116 }117 } 118 119 //堆排序 120 void stack(int arr[], int length){121 start_time = clock(); 122 int i,k,m = 0;123 for(i = length/2-1; i >=0; i--){124 adjust(arr,i,length-1);125 } 126 //调整堆127 for(i = length-1 ;i >= 0; i--){ 128 //调整后把最后一个和第一个交换,每次调整少一个元素,依次向前 129 k = arr[i];130 arr[i] = arr[0];131 arr[0] = k;132 adjust(arr,0,i-1);133 }134 end_time = clock(); 135 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000;136 cout <<right ; cout <<setw(7) <<times<<"ms";137 }138 139 //归并排序合并函数 140 void mergeSoft(int a[], int first, int mid, int last, int temp[]){141 int i = first, j = mid + 1; 142 int m = mid, n = last; 143 int k = 0; 144 while (i <= m && j <= n){ 145 if (a[i] <= a[j]){146 temp[k++] = a[i++]; 147 }else{148 temp[k++] = a[j++]; 149 }150 } 151 while (i <= m){152 temp[k++] = a[i++]; 153 }154 while (j <= n){155 temp[k++] = a[j++]; 156 } 157 158 for (i = 0; i < k; i++){159 a[first + i] = temp[i]; 160 } 161 } 162 163 //归并排序递归拆分函数164 void mergerSelf(int arr[], int left, int right, int arrTmp[]){165 if(left < right){166 int center = (left + right)/2;167 mergerSelf(arr, left, center, arrTmp);168 mergerSelf(arr, center+1, right, arrTmp);169 mergeSoft(arr, left, center, right, arrTmp);170 }171 } 172 //归并排序 173 void merger(int arr[], int n){174 start_time = clock(); 175 int *arrTmp = new int[n];176 mergerSelf(arr, 0, n - 1, arrTmp);177 delete[] arrTmp;178 //记录时间 179 end_time = clock(); 180 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000;181 cout <<right ; cout <<setw(7) <<times<<"ms";182 } 183 184 //快速排序的元素移动 185 int fastSort(int arr[], int left, int right){186 int center = (left+right)/2;187 int num = arr[center]; //记录中枢点的位置,这里选择最左边点当做中枢点 188 while(left < right){189 //比枢纽小的移动到左边 190 while(left < right && arr[right] >= num){191 right--; //一直到有一个元素小于所选关键中枢为止 192 }193 arr[left] = arr[right];194 195 while(left < right && arr[left] <= num){196 left++; //一直到有一个元素大于所选关键中枢为止 197 }198 arr[right] = arr[left]; //关键字入列 199 }200 arr[left] = num;201 return left; 202 } 203 204 //快速排序递归划分205 int fastSortSelf(int arr[], int left, int right){206 if(left < right){207 int lowLocation = fastSort(arr,left,right); //第一个指针的位置 208 fastSortSelf(arr,left,lowLocation - 1); 209 fastSortSelf(arr,lowLocation + 1,right);210 }211 } 212 213 //快速排序 214 void fast(int arr[], int n){215 start_time = clock(); 216 fastSortSelf(arr,0,n-1);217 //记录时间218 end_time = clock(); 219 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000;220 cout <<right ; cout <<setw(7) <<times<<"ms";221 } 222 223 int main(){224 cout<<"\n****************************整数最坏(逆序)测试***********************\n\n"; 225 cout<<"数据量 冒泡 选择 插入 希尔 堆 归并 快速\n";226 int size; //记录每个测试数量 227 int tmpNum; //记录临时数 228 int arr1[8] = {49,38,65,97,76,13,27,49};229 //测试数据的各个范围 230 int nums[6] = {100,1000,5000,10000,30000,50000};231 /*232 printfArr(arr1,8);233 printf("\n");234 fast(arr1,8);235 printfArr(arr1,8);*/236 237 for(int p = 0; p < 6; p++){238 size = nums[p];239 int arrs1[size],arrs2[size],arrs3[size],arrs4[size],arrs5[size],arrs6[size],arrs7[size];240 cout<<left; cout <<"n="<<setw(6)<<size;241 //产生有序数 242 for(int m = 0; m < size; m++){243 int tmpNum = size - m;244 arrs1[m] = tmpNum;245 arrs2[m] = tmpNum;246 arrs3[m] = tmpNum;247 arrs4[m] = tmpNum;248 arrs5[m] = tmpNum;249 arrs6[m] = tmpNum;250 arrs7[m] = tmpNum;251 }252 bubbling(arrs1,size); //冒泡排序法253 directDialing(arrs2,size);//直接选择排序254 insert(arrs3,size); //直接插入排序255 Heer(arrs4,size); //希尔排序256 stack(arrs5,size); //堆排序 257 merger(arrs6,size); //归并排序 258 fast(arrs7,size); //快速排序259 cout<<"\n";260 } 261 262 //*****************随机数测试法******************263 int number;264 int nlong; //数据量 265 cout<<"\n******************************随机数测试*******************************\n\n";266 cout<<"数据量 冒泡 选择 插入 希尔 堆 归并 快速\n";267 for(int r = 0; r < 6; r++){268 size = nums[r];269 int rands1[size],rands2[size],rands3[size],rands4[size],rands5[size],rands6[size],rands7[size];270 //产生测试随机数 271 srand((unsigned) time(NULL));272 for (int rd = 0; rd < size; rd++){273 tmpNum = rand() % size;274 rands1[rd] = tmpNum;275 rands2[rd] = tmpNum;276 rands3[rd] = tmpNum;277 rands4[rd] = tmpNum;278 rands5[rd] = tmpNum;279 rands6[rd] = tmpNum;280 rands7[rd] = tmpNum;281 } 282 //输出测试数据量 283 cout<<left; cout <<"n="<<setw(6)<<size;284 //依次调用各个排序函数 285 bubbling(rands1,size); //冒泡排序法286 directDialing(rands2,size);//直接选择排序287 insert(rands3,size); //直接插入排序288 Heer(rands4,size); //希尔排序289 stack(rands5,size); //堆排序 290 merger(rands6,size); //归并排序 291 fast(rands7,size); //快速排序292 cout<<"\n";293 } 294 }
六、归并排序
将两个和两个以上的排序表合成一个新的有序表,归并排序是分治法思想运用的一个典范。
1:简要过程:
将有 n个对象的原始序 列看作 n个有序子列,每个序列的长度为1,从第一个子序列开始,把相邻的子序列两两合并得到[n/2]个长度为2或者是1的归并项,(如果n为奇数,则最后一个有序子序列的长度为1),称这一个过程为一趟归并排序。
然后重复上述过程指导得到一个长度为n的序列为止。
2:排序效率:
一趟归并排序的操作是:调用[n/2b]次算法,整个过程需要[log2n]趟,课件归并排序时间复杂度是O(logn)
3:排序过程图:
4:具体算法实现:
1 //归并排序合并函数 2 void mergeSoft(int a[], int first, int mid, int last, int temp[]){ 3 int i = first, j = mid + 1; 4 int m = mid, n = last; 5 int k = 0; 6 while (i <= m && j <= n){ 7 if (a[i] <= a[j]){ 8 temp[k++] = a[i++]; 9 }else{10 temp[k++] = a[j++]; 11 }12 } 13 while (i <= m){14 temp[k++] = a[i++]; 15 }16 while (j <= n){17 temp[k++] = a[j++]; 18 } 19 20 for (i = 0; i < k; i++){21 a[first + i] = temp[i]; 22 } 23 } 24 25 //归并排序递归拆分函数26 void mergerSelf(int arr[], int left, int right, int arrTmp[]){27 if(left < right){28 int center = (left + right)/2;29 mergerSelf(arr, left, center, arrTmp);30 mergerSelf(arr, center+1, right, arrTmp);31 mergeSoft(arr, left, center, right, arrTmp);32 }33 } 34 //归并排序 35 void merger(int arr[], int n){36 int *arrTmp = new int[n];37 mergerSelf(arr, 0, n - 1, arrTmp);38 delete[] arrTmp;39 }
七、快速排序
快速排序是一种交换排序,说白了就是一种对起泡排序的改进,不过改进了不少,快速排序被认为是最好的一种排序算法(同量级别)。
1:简要过程:
选择一个基准元素,我们称之为中枢,通常选择第一个元素或者最后一个元素,中枢的选择很重要,直接影响排序的性能,这是因为如果代排序列有序,快速排序就退化为冒泡排序。将序列分割成左右两个序列。其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。一趟排序的具体做法将两个附设指针left和right,然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
2:排序效率:
在所有同级别的排序算法中其平均性能最好O(nlogn)。如果代排序列有序,快速排序就退化为冒泡排序,效率及其低下,这个可以在下面的效率比拼图中体现出来逆序的时候快速排序非常慢,效率很低下。所以可以在中枢的选择上优化可以选着最左边和最右边中间的元素取其平均值即可。
3:排序过程图:
4:具体算法实现:
1 //快速排序的元素移动 2 int fastSort(int arr[], int left, int right){ 3 int center = (left+right)/2; 4 int num = arr[center]; //记录中枢点的位置,这里选择最左边点当做中枢点 5 while(left < right){ 6 //比枢纽小的移动到左边 7 while(left < right && arr[right] >= num){ 8 right--; //一直到有一个元素小于所选关键中枢为止 9 }10 arr[left] = arr[right];11 12 while(left < right && arr[left] <= num){13 left++; //一直到有一个元素大于所选关键中枢为止 14 }15 arr[right] = arr[left]; //关键字入列 16 }17 arr[left] = num;18 return left; 19 } 20 21 //快速排序递归划分22 int fastSortSelf(int arr[], int left, int right){23 if(left < right){24 int lowLocation = fastSort(arr,left,right); //第一个指针的位置 25 fastSortSelf(arr,left,lowLocation - 1); 26 fastSortSelf(arr,lowLocation + 1,right);27 }28 } 29 30 //快速排序 31 void fast(int arr[], int n){32 fastSortSelf(arr,0,n-1);33 //记录时间34 }
八、各种算法效率比拼
下面是我自己写的一个算法比拼,测试数据有100-50000都有,分为最坏情况(逆序->正序)和随机情况(随机->正序),测试数据会因为机器的不同而不同,我的是win8,64, 4G,cpu2.5,欢迎大家测试
说明两点:要注意时间的得到方法,需要引入的头文件包括
1 #include <iostream>2 #include <iomanip> 3 #include <stdlib.h>4 #include <time.h>
1 end_time = clock(); 2 程序。。。。3 times = static_cast<double>(end_timestart_time)/CLOCKS_PER_SEC*1000;cout <<right ; cout <<setw(7) <<times<<"ms";
下面是程序代码:
1 #include <iostream> 2 #include <iomanip> 3 #include <stdlib.h> 4 #include <time.h> 5 using namespace std; 6 7 clock_t start_time, end_time; 8 int times; 9 10 void printfArr(int arr[], int n){ 11 for(int i = 0; i < n; i++){ 12 cout<<arr[i]<<" "; 13 } 14 } 15 16 //冒泡排序 17 void bubbling(int arr[], int n){ 18 start_time = clock(); 19 int i, j, temp; 20 for (j = 0; j < n - 1; j++){ 21 for (i = 0; i < n - 1 - j; i++){ 22 if(arr[i] > arr[i + 1]){ 23 temp = arr[i]; 24 arr[i] = arr[i + 1]; 25 arr[i + 1] = temp; 26 } 27 } 28 } 29 end_time = clock(); 30 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000; 31 cout <<right ; cout <<setw(7) <<times<<"ms"; 32 } 33 34 //直接选择排序 35 void directDialing(int arr[], int n){ 36 start_time = clock(); 37 int i,j,k,num; 38 for(i = 0; i < n; i++){ 39 num = 0; 40 for(j = 0; j < n-i; j++){ 41 if(arr[j] > arr[num]){ 42 num = j; 43 } 44 } 45 k = arr[n-i-1]; 46 arr[n-i-1] = arr[num]; 47 arr[num] = k; 48 } 49 end_time = clock(); 50 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000; 51 cout <<right ; cout <<setw(7) <<times<<"ms"; 52 } 53 54 //直接插入排序 (On2) 55 void insert(int arr[], int n){ 56 start_time = clock(); 57 int m,i,k; 58 for(i = 1; i < n; i++){ 59 m = arr[i]; 60 for(k = i-1; k >= 0; k--){ 61 if(arr[k] > m){ 62 arr[k+1] = arr[k]; 63 }else{ 64 break; 65 } 66 } 67 arr[k+1] = m; 68 } 69 end_time = clock(); 70 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000; 71 cout <<right ; cout <<setw(7) <<times<<"ms"; 72 } 73 74 //希尔排序 75 void Heer(int arr[], int n){ 76 start_time = clock(); 77 int i,j,k,num; 78 k = n/2; 79 while(k > 0){ 80 for(i = k; i < n; i++){ 81 num = arr[i]; 82 for(j = i - k;j >= 0; j -= k){ 83 if(arr[j] > num){ 84 arr[j+k] = arr[j]; 85 }else{ 86 break; 87 } 88 } 89 arr[j+k] = num; 90 } 91 k = k/2; 92 } 93 end_time = clock(); 94 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000; 95 cout <<right ; cout <<setw(7) <<times<<"ms"; 96 } 97 98 //堆调整 99 void adjust(int arr[], int n, int length){100 int max,b;101 while(n * 2 +1 <= length){//说明存在左节点 102 max = n * 2 + 1;103 if(n * 2 + 2 <= length){//说明存在右节点 104 if(arr[max] < arr[n * 2 + 2]){105 max = n * 2 + 2; //跟新最小的值 106 } 107 } 108 if(arr[n] > arr[max]){109 break;//顺序正确,不需要再调整 110 }else{111 b = arr[n];112 arr[n] = arr[max];113 arr[max] = b;114 n = max;115 }116 }117 } 118 119 //堆排序 120 void stack(int arr[], int length){121 start_time = clock(); 122 int i,k,m = 0;123 for(i = length/2-1; i >=0; i--){124 adjust(arr,i,length-1);125 } 126 //调整堆127 for(i = length-1 ;i >= 0; i--){ 128 //调整后把最后一个和第一个交换,每次调整少一个元素,依次向前 129 k = arr[i];130 arr[i] = arr[0];131 arr[0] = k;132 adjust(arr,0,i-1);133 }134 end_time = clock(); 135 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000;136 cout <<right ; cout <<setw(7) <<times<<"ms";137 }138 139 //归并排序合并函数 140 void mergeSoft(int a[], int first, int mid, int last, int temp[]){141 int i = first, j = mid + 1; 142 int m = mid, n = last; 143 int k = 0; 144 while (i <= m && j <= n){ 145 if (a[i] <= a[j]){146 temp[k++] = a[i++]; 147 }else{148 temp[k++] = a[j++]; 149 }150 } 151 while (i <= m){152 temp[k++] = a[i++]; 153 }154 while (j <= n){155 temp[k++] = a[j++]; 156 } 157 158 for (i = 0; i < k; i++){159 a[first + i] = temp[i]; 160 } 161 } 162 163 //归并排序递归拆分函数164 void mergerSelf(int arr[], int left, int right, int arrTmp[]){165 if(left < right){166 int center = (left + right)/2;167 mergerSelf(arr, left, center, arrTmp);168 mergerSelf(arr, center+1, right, arrTmp);169 mergeSoft(arr, left, center, right, arrTmp);170 }171 } 172 //归并排序 173 void merger(int arr[], int n){174 start_time = clock(); 175 int *arrTmp = new int[n];176 mergerSelf(arr, 0, n - 1, arrTmp);177 delete[] arrTmp;178 //记录时间 179 end_time = clock(); 180 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000;181 cout <<right ; cout <<setw(7) <<times<<"ms";182 } 183 184 //快速排序的元素移动 185 int fastSort(int arr[], int left, int right){186 int center = (left+right)/2;187 int num = arr[center]; //记录中枢点的位置,这里选择最左边点当做中枢点 188 while(left < right){189 //比枢纽小的移动到左边 190 while(left < right && arr[right] >= num){191 right--; //一直到有一个元素小于所选关键中枢为止 192 }193 arr[left] = arr[right];194 195 while(left < right && arr[left] <= num){196 left++; //一直到有一个元素大于所选关键中枢为止 197 }198 arr[right] = arr[left]; //关键字入列 199 }200 arr[left] = num;201 return left; 202 } 203 204 //快速排序递归划分205 int fastSortSelf(int arr[], int left, int right){206 if(left < right){207 int lowLocation = fastSort(arr,left,right); //第一个指针的位置 208 fastSortSelf(arr,left,lowLocation - 1); 209 fastSortSelf(arr,lowLocation + 1,right);210 }211 } 212 213 //快速排序 214 void fast(int arr[], int n){215 start_time = clock(); 216 fastSortSelf(arr,0,n-1);217 //记录时间218 end_time = clock(); 219 times = static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000;220 cout <<right ; cout <<setw(7) <<times<<"ms";221 } 222 223 int main(){224 cout<<"\n****************************整数最坏(逆序)测试***********************\n\n"; 225 cout<<"数据量 冒泡 选择 插入 希尔 堆 归并 快速\n";226 int size; //记录每个测试数量 227 int tmpNum; //记录临时数 228 int arr1[8] = {49,38,65,97,76,13,27,49};229 //测试数据的各个范围 230 int nums[6] = {100,1000,5000,10000,30000,50000};231 /*232 printfArr(arr1,8);233 printf("\n");234 fast(arr1,8);235 printfArr(arr1,8);*/236 237 for(int p = 0; p < 6; p++){238 size = nums[p];239 int arrs1[size],arrs2[size],arrs3[size],arrs4[size],arrs5[size],arrs6[size],arrs7[size];240 cout<<left; cout <<"n="<<setw(6)<<size;241 //产生有序数 242 for(int m = 0; m < size; m++){243 int tmpNum = size - m;244 arrs1[m] = tmpNum;245 arrs2[m] = tmpNum;246 arrs3[m] = tmpNum;247 arrs4[m] = tmpNum;248 arrs5[m] = tmpNum;249 arrs6[m] = tmpNum;250 arrs7[m] = tmpNum;251 }252 bubbling(arrs1,size); //冒泡排序法253 directDialing(arrs2,size);//直接选择排序254 insert(arrs3,size); //直接插入排序255 Heer(arrs4,size); //希尔排序256 stack(arrs5,size); //堆排序 257 merger(arrs6,size); //归并排序 258 fast(arrs7,size); //快速排序259 cout<<"\n";260 } 261 262 //*****************随机数测试法******************263 int number;264 int nlong; //数据量 265 cout<<"\n******************************随机数测试*******************************\n\n";266 cout<<"数据量 冒泡 选择 插入 希尔 堆 归并 快速\n";267 for(int r = 0; r < 6; r++){268 size = nums[r];269 int rands1[size],rands2[size],rands3[size],rands4[size],rands5[size],rands6[size],rands7[size];270 //产生测试随机数 271 srand((unsigned) time(NULL));272 for (int rd = 0; rd < size; rd++){273 tmpNum = rand() % size;274 rands1[rd] = tmpNum;275 rands2[rd] = tmpNum;276 rands3[rd] = tmpNum;277 rands4[rd] = tmpNum;278 rands5[rd] = tmpNum;279 rands6[rd] = tmpNum;280 rands7[rd] = tmpNum;281 } 282 //输出测试数据量 283 cout<<left; cout <<"n="<<setw(6)<<size;284 //依次调用各个排序函数 285 bubbling(rands1,size); //冒泡排序法286 directDialing(rands2,size);//直接选择排序287 insert(rands3,size); //直接插入排序288 Heer(rands4,size); //希尔排序289 stack(rands5,size); //堆排序 290 merger(rands6,size); //归并排序 291 fast(rands7,size); //快速排序292 cout<<"\n";293 } 294 }
- 经典的排序算法
- 经典的排序算法
- 经典的排序算法
- 几个经典的排序算法
- 经典的冒泡排序算法
- java的经典排序算法
- 经典的快速排序算法
- 【排序】经典排序算法的汇总测试
- 经典的排序算法--堆排序
- 算法:一些经典的排序算法
- 舞动的排序算法[经典排序算法娱乐版]
- 经典的排序算法--选择排序与冒泡排序
- 经典的排序算法--选择排序与冒泡排序
- 求全排序的经典算法“后补法”
- java的相关排序算法,经典
- 经典排序算法的C++ template封装
- C#的四种排序--经典算法
- 贴两个经典的排序算法
- ORACLE 表空间扩展方法
- 语义分割网络FRRN坑点记录
- 人工智能、机器学习和认知计算入门指南
- Nginx--官网中文翻译(中英文对比)--9-nginx怎样处理一个请求How nginx processes a request
- ASP.NET – 数据绑定
- 经典的排序算法
- Maven install命令
- MIMO技术杂谈(二):犹抱琵琶半遮面--MIMO信道中隐藏的秘密
- 整数中1出现的次数
- vue.js基础-属性与方法和实例生命周期
- Struts2学习笔记(九)——国际化
- 解决Myeclipse或Eclipse出现JPA project Change Event Handler问题的解决办法
- thymeleaf 使用 & 符号问题
- 2017 Multi-University Training Contest