首先,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. 【POJ1185】炮兵阵地(状压DP)

    题意: 思路:状压DP经典题 可以预处理下每一行内合法的状态,发现很少 所以转移时可以使用状态的编号而不是状态本身 DP时记录前两行状态的编号进行转移和判断 #include<cstdio> ...

  2. 「CodePlus 2018 3 月赛」白金元首与克劳德斯

    所有的云在此时没有重叠的面积 所有的云在此时没有重叠的面积 所有的云在此时没有重叠的面积 所有的云在此时没有重叠的面积 所有的云在此时没有重叠的面积 所有的云在此时没有重叠的面积 所有的云在此时没有重 ...

  3. php中memcache与memcached的区别 【收藏】

    说法一:    两个不同版本的php的memcached的客户端 new memcache是pecl扩展库版本new memcached是libmemcached版本功能差不多 说法二:    Mem ...

  4. Swift--错误集:couldn’t be opened because you don’t have permission to view it

    bug复现过程  把snapkit拉入代码中时,也把里面的info.plist文件拖到项目中,运行时,提示“couldn’t be opened because you don’t have perm ...

  5. linux 中断机制浅析

    一.中断相关结构体 1.irq_desc中断描述符 struct irq_desc { #ifdef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED struct irq_ ...

  6. Samba简单配置--匿名用户共享资料可读可写的实现

    http://e-mailwu.blog.163.com/blog/static/65104036200931893921923/ http://www.cnblogs.com/god_like_do ...

  7. Linux系统启动流程分析

    作者:郭孝星 微博:郭孝星的新浪微博 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells Github:https://github.co ...

  8. OpenCV图像处理篇之图像平滑

    图像平滑算法 图像平滑与图像模糊是同一概念,主要用于图像的去噪.平滑要使用滤波器.为不改变图像的相位信息,一般使用线性滤波器,其统一形式例如以下: %20\Large%20g(i,j)=\sum_{k ...

  9. Hadoop之中的一个:Hadoop的安装部署

    说到Hadoop不得不说云计算了,我这里大概说说云计算的概念,事实上百度百科里都有,我仅仅是copy过来,好让我的这篇hadoop博客内容不显得那么单调.骨感.云计算近期今年炒的特别火,我也是个刚開始 ...

  10. POJ 1125 Stockbroker Grapevine (Floyd最短路)

    Floyd算法计算每对顶点之间的最短路径的问题 题目中隐含了一个条件是一个人能够同一时候将谣言传递给多个人 题目终于的要求是时间最短.那么就要遍历一遍求出每一个点作为源点时,最长的最短路径长是多少,再 ...