一、希爾排序算法
(1)、算法思想:希爾排序是插入排序的改良算法,增長了一個步長step,每次插入排序使步長爲step的元素造成一個遞增序列,而後縮小增量,繼續插入,直至step=1時,就是插入排序了,此時排序完成;shell
算法模型:數組
(2)、代碼實現ide
#include<stdio.h> void insertSort(int *a, int count, int step); void showArray(int *a, int count); void shellSort(int *a, int count); void shellSort(int *a, int count){ int step; for(step = count/2; step > 0; step /= 2){ insertSort(a, count, step); } } void showArray(int *a, int count){ int i; for(i = 0; i < count; i++){ printf("%d ", a[i]); } printf("\n"); } //如下就是插入排序了,思想徹底同樣,只不過步長爲step而已!!! void insertSort(int *a, int count, int step){ int i; int j; int n; int tmp; for(i = step; i < count; i+=step){ tmp = a[i]; for(j = 0; a[i]>a[j] && j<i; j+=step){ ; } if(i != j){ for(n = i; n > j; n-=step){ a[n] = a[n-step]; } a[j] = tmp; } } } void main(void){ int a[] = {2, 7, 1, 11, 0, 9, 8, 10}; int count = sizeof(a)/sizeof(int); printf("排序前輸出以下: "); showArray(a, count); shellSort(a, count); printf("排序後輸出以下: "); showArray(a, count); }
(3)、結果截圖ui
(4)、算法分析spa
時間複雜度爲:O(nlogn);3d
二、堆排blog
(1)、算法思想:對無序數組先構建小堆(徹底二叉樹結構),每次刪除堆頂元素(用最後一個元素直接覆蓋第一個元素),每次輸出堆頂元素就行;排序
小堆:根(父)結點比左右孩子都小的數字;
遞歸
(2)、代碼實現
#include<stdio.h> void heapSort(int *a, int count); void siftDown(int *a, int count, int start); void swap(int *a, int *b); int removeHeap(int *a, int n); int removeHeap(int *a, int n){ int key = a[0]; a[0] = a[n]; siftDown(a, n, 0); return key; } void swap(int *a, int *b){ int tmp; tmp = *a; *a = *b; *b = tmp; } void siftDown(int *a, int count, int start){ int i = start; int j = 2*i+1; while(j < count){ //說明有左子樹 if(j < count-1 && a[j] > a[j+1]){ //表示存在右孩子的狀況下; j++; //j:表示指向左右子樹中最小的一個 } if(a[i] <= a[j]){ break; //不用調整,父節點的值是最小的; }else{ swap(&a[i], &a[j]); //交換 i = j; //一直往樹下交換,一直調整到葉子結點 j = 2*i+1; } } } void heapSort(int *a, int count){ int curPos = count/2-1; //最後一個非葉子結點 int i; int key; while(curPos >= 0){ siftDown(a, count, curPos); curPos--; } /* 輸出構建好的堆結構 for(i = 0; i < count; i++){ printf("%d ", a[i]); } printf("\n"); */ for(i = 0; i < count; i++){ key = removeHeap(a, count-i-1); //傳參:第二個參數是下標 printf("%d ", key); } printf("\n"); } void main(void){ int a[] = {3, 5, 7, 1, 4, 2, 9, 10}; int count = sizeof(a)/sizeof(int); heapSort(a, count); }
(3)、結果截圖
(4)、算法分析
時間複雜度:O(nlogn);
三、快速排序
(1)、算法思想:分治的思想,一輪下來將第一個數放到了數字大小的中間,通過屢次遞歸完成排序算法;
(2)、代碼實現
#include<stdio.h> int oneQuickSort(int *a, int i, int j); void quickSort(int *a, int i, int j); void showArray(int *a, int count); void showArray(int *a, int count){ int i; for(i = 0; i < count; i++){ printf("%d ", a[i]); } printf("\n"); } void quickSort(int *a, int i, int j){ int index; if(i < j){ index = oneQuickSort(a, i, j); quickSort(a, i, index-1); quickSort(a, index+1, j); } } int oneQuickSort(int *a, int i, int j){ int tmp; tmp = a[i]; while(i < j){ while(i < j && a[j] > tmp){ j--; } if(i < j){ a[i++] = a[j]; } while(i < j && a[i] < tmp){ i++; } if(i < j){ a[j--] = a[i]; } } a[i] = tmp; return i; } void main(void){ int a[] = {3, 7, 1, 0, 9, -9,}; int count = sizeof(a)/sizeof(int); quickSort(a, 0, count-1); showArray(a, count); }
(3)、結果截圖
(4)、解法二代碼實現
#include<stdio.h> int quickSortOne(int *a, int count){ int i = 0; int j; int tmp; if(a[0] > a[1]){ tmp = a[0]; a[0] = a[1]; a[1] = tmp; } for(j = 2; j < count; j++){ if(a[j] < a[0]){ tmp = a[j]; a[j] = a[++i]; a[i] = tmp; } } tmp = a[0]; a[0] = a[i]; a[i] = tmp; return i; } void quickSort(int *a, int count){ int index = 0; if(index < count-1){ index = quickSortOne(a, count); quickSort(a, index+1); quickSort(a+index+1, count-index-1); } } void showArray(int *a, int count){ int i; for(i = 0; i < count; i++){ printf("%d ", a[i]); } printf("\n"); } int main(void){ int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; int count = sizeof(a)/sizeof(int); int index; quickSort(a, count); showArray(a, count); return 0; }
(5)、算法分析
時間複雜度:O(nlogn);
最壞狀況:已經排好序或徹底逆序,此時時間複雜度:O(n^2);