首先,Shell是发明这个算法的人名,不是这个算法的思想或者特点。

希尔排序,也称为增量递减排序。基本思路,是把原来的序列,等效视为一个矩阵的形式。矩阵的列数,也称为宽度或者增量,记为w。

假设数组A[n]以及矩阵B[][],对于两者的对应关系,可以记为A[k]=B[k/w][k%w]。也就是说,A中的元素会按照先行后列的顺序排列,即先左后右、先上后下的顺序放入矩阵B中。

对于增量或者说矩阵的宽度w,会有许多策略进行选择。假设w={1,2,4,8,16,32...}。从w的集合中选择小于数组元素数量n的最大元素w[i],并且选取w[0]到w[i]之间的所有增量,从w[i]开始,按照矩阵B中的每一列进行排序。这里的排序必须是输入敏感的,通常采用插入排序。本次完成后,取下一个w,再按照每列进行排序。直到w=1,矩阵退化为向量,排序完成。

 int max(int* H, int n, int size)
{
int i = ;
while (i < n&&size > H[i]) i++;
return i - ;
}
void shellSort(int* A, int lo, int hi)//[lo,hi)
{
int H[] = { ,,,,,,,,,, };
int size = hi - lo;
int gap = max(H,,size);//选取小于规模的最大增量
for (int t = gap; t >= ; t--)//从W[gap]一直到w=1,递减增量
{
int w = H[t];//选取步长,w即增量也是宽度(列数)
for (int k = ; k < w; k++)//对于每一列
{
for (int i = lo + w; i < hi; i += w)//下面的循环即插入排序
{
int j = i - w;
int tmp = A[i];
while ((j >= lo) && (A[j] > tmp))
{
A[j + w] = A[j];
j -= w;
}
A[j + w] = tmp;
}//一列的插入排序结束
}//每列都进行插入排序
}
}

希尔排序的总体策略,就是通过按列排序,使得每次排序后的局部有序性增加,最后达到全序列排序的目的。具体的证明可以参考《数据结构C++语言版》,有比较详细的h-有序和(g,h)-有序以及有序性增加的介绍。

下面是一个n=12,w{1,5}的过程。可以看到,w=5排序过后,有序性确实会有一定增加。

希尔排序的复杂度,取决于增量序列w的选择。几个比较优秀的序列,Pratt序列{1,2,3,4,6,8,9,12,..2^p*3^q,...}。这个序列的缺点很明显,会造成排序迭代次数很多,不过时间复杂度可以达到O(nlog^2n)。Sedgewick序列{1,5,19,41,109,209,505,929,2161,3905,8929...}的时间扶再度在最坏情况下可以为O(n^(4/3)),最好情况下为O(n^(7/6).

希尔排序(Shellsort)的更多相关文章

  1. 直接插入排序与缩小增量插入排序(希尔排序ShellSort)

    直接插入排序 要理解shell排序,首先要把直接插入排序的基础打扎实. 学习资料:白话经典算法系列之二 直接插入排序的三种实现.直接插入排序 根据我的思路,直接插入排序设置3重循环. 循环1:对 i= ...

  2. 【算法】【排序】【插入类】希尔排序 ShellSort

    #include<stdio.h> #include <time.h> #include<stdlib.h> int main(){ ]; //设立随机数 sran ...

  3. 【Sort】希尔排序

    希尔排序(ShellSort),缩小增量排序,使用希尔增量时最坏运行时间O(n^2),不同的增量会对运行时间产生显著影响. void shellsort(int *nums,int n) { int ...

  4. 几种排序方式的java实现(02:希尔排序,归并排序,堆排序)

    代码(部分为别人代码): 1.希尔排序(ShellSort) /* * 希尔排序:先取一个小于n的整数d1作为第一个增量, * 把文件的全部记录分成(n除以d1)个组.所有距离为d1的倍数的记录放在同 ...

  5. Java基础知识强化57:经典排序之希尔排序(ShellSort)

    1. 希尔排序的原理: 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于1959年提出 ...

  6. C#数据结构与算法系列(二十一):希尔排序算法(ShellSort)

    1.介绍 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序. 2.基本思想 希尔排 ...

  7. 排序--ShellSort 希尔排序

    希尔排序 no 实现 希尔排序其实就是插入排序.只不过希尔排序在比较的元素的间隔不是1. 我们知道插入排序 都是 一个一个和之前的元素比较.发现比之前元素小就交换位置.但是希尔排序可能是和前第n个元素 ...

  8. uva 10152 ShellSort 龟壳排序(希尔排序?)

    今天状态总是很糟,这种题目卡了一天... 是不是休息时间太少了,头脑迟钝了... 名字叫希尔排序,我还以为跟它有关,还搜索了下资料. 只要找到trick就会发现是很水的题目.只要对比下就能找到哪些是移 ...

  9. 希尔排序的正确性 (Correctness of ShellSort)

    学希尔排序的时候,觉得有序性保持的性质十分神奇,但哪里都找不到数学证明.最后在Donald E. Knuth的The Art of Computer Programming中找到了(显然我没有读过这套 ...

随机推荐

  1. 【Educational Codeforces Round 48】

    A:https://www.cnblogs.com/myx12345/p/9843001.html B:https://www.cnblogs.com/myx12345/p/9843021.html ...

  2. BZOJ1583: [Usaco2009 Mar]Moon Mooing 哞哞叫

    给n<=4000000,c,a1,b1,c1,a2,b2,c2,以c为初始得到的数,每次可以把得到的某个数x进行操作f1(x)=a1*x/c1+b1,f2(x)=a2*x/c2+b2,求最后能得 ...

  3. mysql 时间类型datetime与timestamp区别比较

    mysql 时间类型datetime与timestamp区别比较 相同点: 显示宽度和格式相同,显示宽度固定在19字符,格式为YYYY-MM-DD HH:MM:SS. 不同点: (1)时间范围不同: ...

  4. Xcode warning:Auto property synthesis will not synthesize property

    iOS 警告提示如下: 添加 @dynamic告诉编译器这个属性是动态的,动态的意思是等你编译的时候就知道了它只在本类合成; 如下:

  5. CodeForces 598C Nearest vectors

    这题对精度要求很高.用atan2吧... #include<iostream> #include<cstring> #include<cmath> #include ...

  6. Node.js+Web TWAIN,实现Web文档扫描和图像上传

      目录(?)[+] 通过Dynamic Web TWAIN SDK和Node.js的组合,只需要几行代码就可以实现在浏览器中控制扫描仪,获取图像后上传到远程服务器. 原文:Document Imag ...

  7. L0、L1与L2范数

    监督机器学习问题无非就是“minimize your error while regularizing your parameters”,也就是在正则化参数的同时最小化误差.最小化误差是为了让我们的模 ...

  8. 【stl学习笔记】list

    list使用双向链表来管理元素. 与vector.deque的区别: 1.list不支持随机存取,在list中随机遍历任意元素,是很缓慢的行为 2.任何位置上执行元素的安插和移除都非常快,始终是常数时 ...

  9. Android - 渠道号(vender)

    渠道号(vender) 本文地址: http://blog.csdn.net/caroline_wendy Android的apk公布,须要统计各个渠道(vendor)的激活数.就能够使用vendor ...

  10. vue 定义全局函数

    方法一:main.js 注入 (1)在main.js中写入函数 Vue.prototype.changeData = function (){ alert('执行成功'); } (2)在所有组件里可调 ...