希尔排序(及其与直接插入排序的区别)
2015-10-10 21:27
1301 查看
希尔排序基本思想
基本思想:
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
该方法实质上是一种分组插入方法。
Shell排序的算法实现
与直接插入排序比较,希尔排序的改进如下:
1、增加了一个for语句,用于控制步长变化。
2、不设置监视哨,故在寻找插入点的for语句中增加j>0来防止访问越界。
其实,假如去掉这些改进,我们去掉外层的for,然后把dk替换成1,是否发现算法变成了没有设监视哨的直接插入排序?
看看直接插入排序
性能分析:
1、空间复杂度O(1)。
2、时间复杂度:由于希尔排序的时间复杂度依赖于增量序列的函数。当n在某个特定的范围时,希尔的时间复杂度约为O(n^1.3),最坏的情况下希尔排序的时间复杂度为O(n^2);
到目前为止,尚未得出一个最好的增量方法序列,希尔提出的方法是d[1]=n/2,d[t]=d[t-1]/2,其中,增量取整数。
稳定性:不稳定
基本思想:
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
该方法实质上是一种分组插入方法。
Shell排序的算法实现
void ShellSort(ElemType A,int n) { int i,j,dk; for(dk=n/2;dk>=1;dk=dk/2)//控制步长变化,每次步长缩小为原来的1/2,直到1 { for(i=dk+1;i<n;i++)//前dk个默认为dk组的已序 { if(A[i].key<A[i-dk].key) { A[0]=A[i];//暂存A[i],这里不是监视哨; for(j=i-dk;j>0&&A[0].key<A[j].key;j-=dk)//选寻找插入点 A[j+dk]=A[j];//记录后移 A[j]=A[0]; } } } }
与直接插入排序比较,希尔排序的改进如下:
1、增加了一个for语句,用于控制步长变化。
2、不设置监视哨,故在寻找插入点的for语句中增加j>0来防止访问越界。
其实,假如去掉这些改进,我们去掉外层的for,然后把dk替换成1,是否发现算法变成了没有设监视哨的直接插入排序?
void InsertSort(SeqList R,int n) { int i,j; for(i=2;i<=n;i++) { if(R[i].key<R[i-1].key) { R[0]=R[i]; for(j=i-1;R[0].key<R[j].key;--j) R[j+1]=R[j]; } } R[j]=R[0]; }
看看直接插入排序
性能分析:
1、空间复杂度O(1)。
2、时间复杂度:由于希尔排序的时间复杂度依赖于增量序列的函数。当n在某个特定的范围时,希尔的时间复杂度约为O(n^1.3),最坏的情况下希尔排序的时间复杂度为O(n^2);
到目前为止,尚未得出一个最好的增量方法序列,希尔提出的方法是d[1]=n/2,d[t]=d[t-1]/2,其中,增量取整数。
稳定性:不稳定
相关文章推荐
- Android-ImageSpan的使用实现图文并排
- iOS系统后台运行机制研究
- Ray Sphere 相交测试
- 敏捷测试与传统测试的区别
- 【开源下载】c#编写的聊天程序微风IM 版本2 增加局域网P2P通信
- hadoop之MAPREDUCE
- 黑马程序员——OC基础---协议
- 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序。
- ARM专业术语1
- 排序——快速排序算法
- 用例设计
- hdu--2955
- SGU 347 Join the Strings 字符串 排序 思维
- 树莓派设置无线热点(RTL8188CUS芯片)
- gns3 1.4 使用gns3vm,新的iourc
- HDU2838 Cow Sorting 树状数组
- 软件测试管理体系
- 我的~/.vimrc设置
- hadoop远程调试
- B树算法与实现 (C语言实现)