希尔排序(Shellsort)
首先,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)的更多相关文章
- 直接插入排序与缩小增量插入排序(希尔排序ShellSort)
直接插入排序 要理解shell排序,首先要把直接插入排序的基础打扎实. 学习资料:白话经典算法系列之二 直接插入排序的三种实现.直接插入排序 根据我的思路,直接插入排序设置3重循环. 循环1:对 i= ...
- 【算法】【排序】【插入类】希尔排序 ShellSort
#include<stdio.h> #include <time.h> #include<stdlib.h> int main(){ ]; //设立随机数 sran ...
- 【Sort】希尔排序
希尔排序(ShellSort),缩小增量排序,使用希尔增量时最坏运行时间O(n^2),不同的增量会对运行时间产生显著影响. void shellsort(int *nums,int n) { int ...
- 几种排序方式的java实现(02:希尔排序,归并排序,堆排序)
代码(部分为别人代码): 1.希尔排序(ShellSort) /* * 希尔排序:先取一个小于n的整数d1作为第一个增量, * 把文件的全部记录分成(n除以d1)个组.所有距离为d1的倍数的记录放在同 ...
- Java基础知识强化57:经典排序之希尔排序(ShellSort)
1. 希尔排序的原理: 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于1959年提出 ...
- C#数据结构与算法系列(二十一):希尔排序算法(ShellSort)
1.介绍 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序. 2.基本思想 希尔排 ...
- 排序--ShellSort 希尔排序
希尔排序 no 实现 希尔排序其实就是插入排序.只不过希尔排序在比较的元素的间隔不是1. 我们知道插入排序 都是 一个一个和之前的元素比较.发现比之前元素小就交换位置.但是希尔排序可能是和前第n个元素 ...
- uva 10152 ShellSort 龟壳排序(希尔排序?)
今天状态总是很糟,这种题目卡了一天... 是不是休息时间太少了,头脑迟钝了... 名字叫希尔排序,我还以为跟它有关,还搜索了下资料. 只要找到trick就会发现是很水的题目.只要对比下就能找到哪些是移 ...
- 希尔排序的正确性 (Correctness of ShellSort)
学希尔排序的时候,觉得有序性保持的性质十分神奇,但哪里都找不到数学证明.最后在Donald E. Knuth的The Art of Computer Programming中找到了(显然我没有读过这套 ...
随机推荐
- POJ1256 Anagram
Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %lld & %llu Submit Status Descript ...
- [NOIP1999] 提高组 洛谷P1014 Cantor表
题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 … 2/1 2/2 2/3 2/4 … ...
- C#路径,文件,目录,I/O常见操作汇总
原文发布时间为:2008-10-25 -- 来源于本人的百度文章 [由搬家工具导入] 路径,文件,目录,I/O常见操作汇总 摘要: 文件操作是程序中非常基础和重要的内容,而路径、文件、目录以及 ...
- Codeforces 920G(二分+容斥)
题意: 定义F(x,p)表示的是一个数列{y},其中gcd(y,p)=1且y>x 给出x,p,k,求出F(x,p)的第k项 x,p,k<=10^6 分析: 很容易想到先二分,再做差 然后问 ...
- GAN Generative Adversarial Network 生成式对抗网络-相关内容
参考: https://baijiahao.baidu.com/s?id=1568663805038898&wfr=spider&for=pc Generative Adversari ...
- MAC上反编译android apk---apktool, dex2jar, jd-jui安装使用(含手动签名)
前文 介绍了在Windows平台利用强大的APK-Multi-Tool进行反编译apk,修改smali源码后再回编译成apk的流程,最近受人之托,破解个apk,所幸的是所用到的这三个软件都是跨平台的, ...
- Python遍历路径下文件并转换成UTF-8编码
http://www.cnblogs.com/wuyuegb2312/archive/2013/01/11/2856772.html 开始学Python,这篇文章来自于应用需求. os.walk很方便 ...
- 2>MSVCRTD.lib(MSVCR100D.dll) : error LNK2005: _calloc 已经在 LIBCMTD.lib(dbgcalloc.obj) 中定义
使用VS2010,在FireBreath里面调用ortp库和Speex库.编译的时候出现错误: 2>MSVCRTD.lib(MSVCR100D.dll) : error LNK2005: _ca ...
- pagePiling.js - 创建美丽的全屏滚动效果
在线演示 在线演示 本地下载 全屏滚动效果是近期很流行的网页设计形式,带给用户良好的视觉和交互体验. pagePiling.js 这款jQuery插件能够帮助前端开发者轻松实现这样的效果.支持全部的主 ...
- LoadRunner系列实例之— 01录制cas登陆脚本
关于CAS 的概念,见链接 需要增加4个关联函数,初次加载页面时取cookie和it1,输入账号密码点击登录时,取ticketGrantingTicketId和it2 实际上前后台完成两次交互, // ...