日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构排序2-希尔,快速,归并排序

發布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构排序2-希尔,快速,归并排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

希爾排序

希爾排序是對插入排序的改進。增加了分組

分組插入排序 降低元素個數,然后對每組分別進行插入排序
利用分組增量遍歷,因為最后必須全部排序一次,然后分別對每組插入排序。把每組的第一個數作為有序序列,
要比較的第一個基準數就是第二個

#include<iostream> #include<stdio.h> #include<stdlib.h> #include<random> #include<time.h> #include<sys/timeb.h> using namespace std; #define MAX 50000long getSystemTime() {struct timeb tb;ftime(&tb);return tb.time * 1000 + tb.millitm; //毫秒 }void printArr(int arr[], int length) {for (int i = 0; i < length; i++){printf("%d ", arr[i]);}printf("\n"); } //插入排序 void insertSort(int arr[], int length) {int j;for (int i = 1; i < length; i++) //從第二個數開始是無序隊列。第一個數為有序隊列{if (arr[i]<arr[i - 1]){int temp = arr[i]; //將滿足條件的元素緩沖到temp中for (j = i - 1; j >= 0 && temp < arr[j]; j--) //將有序數列分別遍歷{arr[j + 1] = arr[j];}arr[j + 1] = temp; //填補坑}} } //錯誤 void shellSortme(int arr[], int length) {int increasement = length;//確定分組的增量increasement = increasement /3+1;int i, j, k;for (i = 0; i < increasement; i++) //外層分組循環,最后等于1時全部再一起排列一次{for (j = i + increasement; j < length; j += increasement) //從i+creasement是無序的第一個數{if (arr[i + increasement] < arr[i]){int temp=arr[i];for (k = i + increasement; k < j && arr[k] < temp; k -= increasement){arr[k] = arr[k + 1];}arr[k + 1] = temp;}}} }void shellSort(int arr[], int length) {int increasement = length;int i, j, k;do {//確定分組的增量increasement = increasement / 3 + 1;//外層分組循環,最后等于1時全部再一起排列一次for (i = 0; i < increasement; i++) {//從i+creasement是無序的第一個數for (j = i + increasement; j < length; j += increasement) {if (arr[j] < arr[j - increasement]){int temp = arr[j];//temp如果大于arr[k]的話,就不需要移動元素。//只有temp小于arr[k]即有序數組的其中一個數,才需要繼續往前移動for (k = j - increasement; k >= 0 && temp<arr[k]; k -= increasement){arr[k + increasement] = arr[k]; //將滿足條件有序的元素往后移動}arr[k + increasement] = temp;}}}} while (increasement > 1); }int main() {int arr[MAX];srand((unsigned int)time(NULL)); //種子for (int i = 0; i < MAX; i++){arr[i] = rand() % MAX;}//printf("未排序數組為:");//printArr(arr, MAX);long t_start = getSystemTime();shellSort(arr, MAX);long t_end = getSystemTime();//printf("希爾排序后數組為:");//printArr(arr, MAX);printf("希爾排序%d個元素,所需時間:%1d\n", MAX, t_end - t_start);system("pause");return 0; }

運行結果:

快速排序

分治法加挖坑填數
找一個基準,小于放左邊,大于放右邊。一直遍歷。填坑。
一般將第一數作為基準數。第一個數下標為i.挖坑。最后一個下標為j,從右邊找一個數填坑。找到小于基準數的然后填坑。則此時j的位置就是坑了,此時從左往右找比基準數大的然后填坑。。。。此時i的地方為坑,繼續一直循環下去,直到i==j時,把基準數填i位置的坑。然后此時i的位置是正確的,然后將i的左邊和右邊分別進行相同的操作。所以用到了遞歸i<j就是遞歸結束條件>

#include<iostream> #include<stdio.h> #include<stdlib.h> #include<random> #include<time.h> #include<sys/timeb.h> using namespace std; #define MAX 50000long getSystemTime() {struct timeb tb;ftime(&tb);return tb.time * 1000 + tb.millitm; //毫秒 }void printArr(int arr[], int length) {for (int i = 0; i < length; i++){printf("%d ", arr[i]);}printf("\n"); }void quickSortme(int arr[], int start, int end) {int mid = (start + end) / 2;int temp = arr[start];int i = start;int j = end;if (i >= j){//從后往前比較,找一個比基準數小的數,放前面if (arr[j] < temp){arr[i] = arr[j];arr[j] = temp;j--;}//從前往后比較,找一個比基準數大的數,放后面if (arr[i] > temp){arr[i] = arr[j];arr[i] = temp;i++;}} } //快速排序,從小到大 void quickSort(int arr[], int start, int end) { int i = start;int j = end;int temp = arr[start]; //作為基準數if (i < j){while (i<j){//從右向左比較,找一個比基準數小的元素,放左邊while (i < j && arr[j] >= temp) //從右往左遍歷,尋找滿足小于基準數的元素{j--;}if (i<j) {arr[i] = arr[j]; //填左邊坑i++;}//從左往右比較,找一個比基準數大的數,放右邊while (i < j && arr[i] <= temp) //從左往右遍歷,尋找滿足大于基準數的元素{i++;}if (i<j){arr[j] = arr[i]; //填右邊坑j--;}}//把基準數放到i位置arr[i] = temp;//對左半部分進行快速排序quickSort(arr,start, i - 1);//對右半部分進行快速排序quickSort(arr, i+1, end);} }int main() {int arr[MAX];srand((unsigned int)time(NULL)); //種子for (int i = 0; i < MAX; i++){arr[i] = rand() % MAX;}//printf("未排序數組為:");//printArr(arr, MAX);long t_start = getSystemTime();quickSort(arr, 0,MAX-1);long t_end = getSystemTime();//printf("冒希爾排序后數組為:");//printArr(arr, MAX);printf("快速排序%d個元素,所需時間:%1d\n", MAX, t_end - t_start);system("pause");return 0; }

結果:

歸并排序

分組,然后排序,然后存到數組,然后覆蓋原來

#include<iostream> #include<stdio.h> #include<stdlib.h> #include<random> #include<time.h> #include<sys/timeb.h> using namespace std; #define MAX 50000long getSystemTime() {struct timeb tb;ftime(&tb);return tb.time * 1000 + tb.millitm; //毫秒 }void printArr(int arr[], int length) {for (int i = 0; i < length; i++){printf("%d ", arr[i]);}printf("\n"); }int* CreateArr() {srand((unsigned int)time(NULL)); //種子int* arr =(int *)malloc(sizeof(int)*MAX);for (int i = 0; i < MAX; i++){arr[i] = rand() % MAX;}return arr; } //合并算法 從小到大 void merge(int arr[], int start, int end, int mid, int *temp) {int i_start = start;int i_end = mid;int j_start = mid + 1;int j_end = end;//表示輔助空間有多少個元素int length = 0;//合并兩個有序序列while (i_start <= i_end && j_start <= j_end){if (arr[i_start] < arr[j_start]){temp[length] = arr[i_start];length++;i_start++;}else{temp[length] = arr[j_start];length++;j_start++;}}//i這個序列while (i_start <= i_end){temp[length] = arr[i_start];length++;i_start++;}//j這個序列while (j_start <= j_end){temp[length] = arr[j_start];length++;j_start++;}//將輔助空間數據覆蓋原空間for (int i = 0; i < length; i++){arr[start+i]=temp[i];} }//歸并排序,將兩個有序序列合并成一個有序序列 不會寫 void mergeSort(int arr[], int start,int end,int *temp) {if (start >= end){return;}int mid = (start + end) / 2;//左半邊mergeSort(arr, start, mid, temp);//右半邊mergeSort(arr, mid+1, end, temp);//合并merge(arr, start, end, mid, temp);}int main() {int *arr = CreateArr();long t_start = getSystemTime();//申請輔助空間int* temp = (int *)malloc(sizeof(int)*MAX);mergeSort(arr, 0, MAX - 1,temp);long t_end = getSystemTime();printf("歸并排序%d個元素,所需時間:%1d\n", MAX, t_end - t_start);/*free(temp);free(arr);*/system("pause");return 0; }

運行結果:

歸并排序示意圖:

思路:

因為題目要求復雜度為O(nlogn),故可以考慮歸并排序的思想。

歸并排序的一般步驟為:

1)將待排序數組(鏈表)取中點并一分為二;

2)遞歸地對左半部分進行歸并排序;

3)遞歸地對右半部分進行歸并排序;

4)將兩個半部分進行合并(merge),得到結果。

參考自https://blog.csdn.net/boguesfei/article/details/80413365

?

總結

以上是生活随笔為你收集整理的数据结构排序2-希尔,快速,归并排序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。