1、希尔排序
(1)、算法思想:希尔排序是插入排序的改良算法,增加了一个步长step,每次插入排序使步长为step的元素形成一个递增序列,然后缩小增量,继续插入,直至step=1时,就是插入排序了,此时排序完成;
算法模型:
(2)、代码实现
#includevoid 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 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)、结果截图
(4)、算法分析
时间复杂度为:O(nlogn);
2、堆排
(1)、算法思想:对无序数组先构建小堆(完全二叉树结构),每次删除堆顶元素(用最后一个元素直接覆盖第一个元素),每次输出堆顶元素就行;
小堆:根(父)结点比左右孩子都小的数字;
(2)、代码实现
#includevoid 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);
3、快速排序
(1)、算法思想:分治的思想,一轮下来将第一个数放到了数字大小的中间,经过多次递归完成排序算法;
(2)、代码实现
#includeint 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)、解法二代码实现
#includeint 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);