《C算法》读书笔记9:希尔排序的性质研究

上文。增量序列h有两条重要性质:

首先,定义h排序结束后的数组为h有序。

1、k排序一个h有序的数组,得到的数组既为k有序也为h有序。

2、当k、h互质时,对该新数组进行g排序,比较次数少于N(k?1)(h?1)/g

下面是一个很不错的增量序列hi=1,8,23,77,281,1073,4193,16577...,经实验发现,它的表现好于hn=3hn?1+1与hn=2hn?1+1。有文献证明,该序列的希尔排序复杂度下界为O(N4/3)。

更进一步,根据性质2,假如一个2有序且3有序的数组进行最后一遍排序(1排序),比较次数为线性。

1971年,pratt提出了一个增量三角形:

该图中每个数都是左上数的三倍,右上数的两倍。实际应用中,可以将{2,3}替换成较大的互质素数对{h,k},以减少序列项的数量。

以下是N=20000时的一组完全随机实验数据:

hn=2hn?1+1

8191 4095 2047 1023 511 255 127 63 31 15 7 3 1

shell sort step 321464

hn=3hn?1+1

9841 3280 1093 364 121 40 13 4 1

shell sort step 387480

hn=2hn?1

8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1

shell sort step 1684506

hi=1,8,23,77,281,1073,4193,16577...

16577 4193 1073 281 77 23 8 1

shell sort step 373642

对该数列进行增项训练,发现在1073和281之间插入一项541,能得到较好结果:

16577 4193 1073 541 281 77 23 8 1

shell sort step 318192

同理,对hn=3hn?1+1研究后发现,将第二项13替换为23,得到结果为局部最优。

9841 3280 1093 364 121 40 23 4 1

shell sort step 342600

由此想到如下改进:

首先固定h0,h2,h3,...,枚举h1,得到最优数列。

接着固定h0,h1,h3,...,枚举h2,得到最优数列。

依次类推,最后得到一个新的数列hi^。

hi=1,5,23,65,175,383,969,2171,4626,9251...

4626 2171 969 383 175 65 23 5 1

shell sort step 269223

best step = 269223, val = 9251

此时,较原增量数列,已提高43%效率。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-27 07:36:25

《C算法》读书笔记9:希尔排序的性质研究的相关文章

经典排序算法学习笔记四——希尔排序

一.希尔排序 数据结构 数组 最差时间复杂度 根据步长序列的不同而不同.已知最好的:O(n*log ^{2}n) 最优时间复杂度 O(n) 平均时间复杂度 根据步长序列的不同而不同. 最差空间复杂度 O(n) 1.算法思想: 先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序: 然后取d2<d1,重复上述分组和排序操作: 直至di=1,即所有记录放进一个组中排序为止. 我是栗子,栗子,栗子 假设有这样一组数[ 13 14 94 33 82 25 59 94 65

让算法会说话之希尔排序

这是我参照之前在iOS项目中用过的一个不规则形状按钮的第三方Button,这里用Cocos2d-x实现一个相似功能的按钮. 原文地址:http://blog.csdn.net/qqmcy/article/details/26161339 代码下载:http://download.csdn.net/detail/qqmcy/7365843 使用方法: .h // // TestScene.h // maptest // // Created by 杜甲 on 14-5-18. // // #ifn

读书笔记:季羡林关于如何做研究学问的心得

以下的内容摘自: 季羡林 (2010-02-01). 牛棚杂忆(季羡林作品珍藏本)(图文版) (Kindle Locations 2701-2706).? . Kindle Edition. ? 我记得,鲁迅先生在一篇文章中讲了一个笑话:一个江湖郎中在市集上大声吆喝,叫卖治臭虫的妙方.有人出钱买了一个纸卷,层层用纸严密裹住.打开一看,妙方只有两个字:勤捉.你说它不对吗?不行,它是完全对的.但是说了等于不说.我的经验压缩成两个字是勤奋.再多说两句就是:争分夺秒,念念不忘.灵感这东西不能说没有,但是

算法-java代码实现希尔排序

希尔排序 第8节 希尔排序练习题 对于一个int数组,请编写一个希尔排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组.保证元素小于等于2000. 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] Java (javac 1.7) 代码自动补全 1 import java.util.*; 2 3 public class ShellSort { 4 public int[] shellSort(int[] A, int n) { 5 int

排序算法(六)——希尔排序

基本思想 希尔排序是基于插入排序的,又叫缩小增量排序. 在插入排序中,标记符左边的元素是有序的,右边的是没有排过序的,这个算法取出标记符所指向的数据,存入一个临时变量,接着,在左边有序的数组中找到临时变量应该插入的位置,然后将插入位置之后的元素依次后移一位,最后插入临时变量中的数据. 试想,假如有一个很小的数据项在靠近右端的位置上,把这个数据项插入到有序数组中时,将会有大量的中间数据项需要右移一位,这个步骤对每一个数据项都执行了将近N次复制.虽然不是所有数据项都必须移动N个位置,但是,数据项平均

图解算法读书笔记

区别于以往的读书笔记 这次采用了思维导图的模式 PHP js Linux  也相继整理自己的思维导图 便于理解和记忆 主要分为 算法  和数据结构两部分 结合书中python的demo,全部敲了一遍 一 算法 提到算法 绕不过去的肯定是大O表示法  也是各种面试问时间复杂度的重点考察的基础问题 二 数据结构 由堆排序再引出 二叉树 红黑树 等等内容 下次再更新 原文地址:https://www.cnblogs.com/Sherlock09/p/9052912.html

1)③排序算法之插入排序[2]希尔排序

1 #include<iostream> 2 using namespace std; 3 4 int shell_sort(int n,int array[100]){//希尔排序法 5 register int dh,temp,i,j; 6 dh=n/2; 7 while(dh>=1){ 8 for( i=dh;i<n;i++){ 9 temp=array[i]; 10 j=i-dh; 11 while(j>=0&&array[j]>temp){ 1

自己整理的算法 (7) 希尔排序

package sort; /**希尔排序的原理:根据需求,如果你想要结果从小到大排列,它会首先将数组进行分组,然后将较大值移到前面,较小值 * 移到后面,最后将整个数组进行插入排序,这样比起一开始就用插入排序减少了数据交换和移动的次数,可以说希尔排序是加强 * 版的插入排序 * 拿数组5, 2, 8, 9, 1, 3,4来说,数组长度为7,当increment为3时,数组分为两个序列 * 5,2,8和9,1,3,4,第一次排序,9和5比较,1和2比较,3和8比较,4和比其下标值小increme

常用算法Java实现之希尔排序

希尔排序严格来说是基于插入排序的思想,又被称为缩小增量排序. 具体流程如下: 1.将包含n个元素的数组,分成n/2个数组序列,第一个数据和第n/2+1个数据为一对... 2.对每对数据进行比较和交换,排好顺序: 3.然后分成n/4个数组序列,再次排序: 4.不断重复以上过程,随着序列减少并直至为1,排序完成. 假如有初始数据:25  11  45  26  12  78. 1.第一轮排序,将该数组分成 6/2=3 个数组序列,第1个数据和第4个数据为一对,第2个数据和第5个数据为一对,第3个数据