赞
踩
单独总结我的另一篇博客:
https://blog.csdn.net/hansionz/article/details/80835834
//直接插入排序 int InsertSort(int *num,int len) { assert(num); int i = 0; //第一个元素已经为有序序列,所以要进行len-1次排序 for (; i < len - 1; i++) { int end = i; int tmp = num[i + 1];//保存非有序区间第一个元素,否则在后边的移动中会改变 //比较后移 while (end >= 0 && num[end]>tmp) { num[end+1] = num[end]; --end; } //插入到适当位置 num[end + 1] = tmp; } }
O(N)
;最坏情况,待排序列基本无序,时间复杂度为O(N*N)
。O(1)
。希尔排序又叫缩小增量排序
,它实质上是一种插入排序。一方面,它的发现者DL.Shell
是基于在我们进行直接插入排序的过程中有的记录
移动的太慢了而且移动的次数很大,那能不能想办法让它移动的快一点呢?于是DL.Shell
想到让记录
按下标的一定增量分组,对每组使用直接插入排序算法排序,最后在进行一次直接插入排序。另一方面,希尔排序是对直接插入排序的优化,它先进行预排序,使得待排序列基本有序,在进行直接插入排序O(N)
,所以它主要分为两步
:
Prepare_y
博主博客中的图片gap
必须等于1,基本有序的记录序列进行一次直接排序得到最终排序结果//希尔排序(缩小增量排序) /*最好步长序列是由Sedgewick提出的(1, 5, 19, 41, 109,...)*/ int ShellSort(int *num, int len) { assert(num); int gap = 5;//步长 //最后一次步长必须为1 while (gap >= 0) { //1.gap>1时预排序 for (int i = 0; i < len - gap; i++) { int end = i; int tmp = num[end + gap]; while (end >= 0 && num[end] > tmp) { num[end + gap] = num[end]; end -= gap; } num[end + gap] = tmp; } gap -= 2; } //2.gap为1时直接插入排序(这时要排序序列已经接近有序) }
希尔排序是基于多次预排序让记录中大的数字较快的移动到后边,使得记录序列基本有序,而不是像直接排序中一个一个往后移动。总的来说希尔排序的效率肯定比直接插入排序要高。因为希尔排序的时间复杂度和它的步长选择有关系,它的平均时间复杂度为n*log(n)
。另外,由于排序序列中数据的相对位置可能变化,所以希尔排序是一种不稳定的排序
。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。