希尔排序(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中找到了(显然我没有读过这套 ...
随机推荐
- 洛谷 P4720 【模板】扩展 / 卢卡斯 模板题
扩展卢卡斯定理 : https://www.luogu.org/problemnew/show/P4720 卢卡斯定理:https://www.luogu.org/problemnew/show/P3 ...
- Python 列表的复制操作
2013-10-18 10:07:03| import copy a = [1,2,3,['a','b']] b = a c = a[:] d = copy.copy(a) e = copy.de ...
- Toy Storage--POJ2398(计算几何)
http://poj.org/problem?id=2398 这道题和上一道TOYS是一样的 就是输出不一样 还有就是这个给的是乱序 你要先对挡板排序 #include <iostrea ...
- POJ 1780 【手工递归】【欧拉回路】
题意: 1.提供密码的位数. 2.密码的输入可以一直保持,取后n位作为密码.如果密码正确则开锁. 3.设计一种方法使得在输入最少的情况下破译.(即保证每个密码只输入一次) 4.输出输入的数字的序列. ...
- Spring Boot应用的启动和停止(Spring Boot应用通过start命令启动)
Spring Boot,作为Spring框架对“约定优先于配置(Convention Over Configuration)”理念的最佳实践的产物,它能帮助我们很快捷的创建出独立运行.产品级别的基于S ...
- Org-mode五分钟教程ZZZ
Table of Contents 1 源起 2 简介 2.1 获取 org-mode 2.2 安装 3 基础用法 3.1 创建一个新文件 3.2 简单的任务列表 3.3 使用标题组织一篇文章 3.4 ...
- 【c++】拷贝控制具体分析
我们可以定义拷贝操作,使类的行为看起来像一个值或者像一个指针,这取决于如何拷贝指针成员. 当我们拷贝一个像值的对象时,副本和原对象是完全独立的,改变副本不会对原对象有任何影响,反之亦然.标准库容器和s ...
- 学习MarkDown--初体验
学习MarkDownPad 突然兴趣来了,在博客园里面也有Markdown的格式,昨天晚上安装了MarkDownPad pro这个是免费的,但是有些功能不支持.本来想破解的,百度了很多方法感觉不靠谱, ...
- jpa删除根据对象删除失败,报Removing a detached instance 错
引用:https://blog.csdn.net/zhanggnol/article/details/6307936 常用数据库表的删除办法,一般都会在DAO类中提供delete.如下例: publi ...
- mysql字段A复制到字段B,并替换指定字符
',字段a); eg:update `hy_b_pro` set goldWeight=jinJinZhong;