1.希尔排序思想:

希尔排序就是把数据分成若干份子序列,从第一个元素开始,和每间隔为n的元素分成一个子序列,对每一份子序列实行直接插入排序,然后合并成一个新序列,继续对新序列以间隔m分成若干份,继续重复步骤,直至一个元素一份,对所有元素实行直接插入排序。如下步骤(注意,实际增量并不是按照-1变化的,我们这里只是为了观看过程,以达到理解希尔排序思想的目的)
第一次分解排序
我们画图举例,比如我们一开始有下列数据,且第一次以间隔4(即增量为4)分成若干子序列:

如上图,间隔为4,分若干个子序列,颜色相同的为一个子序列,那么上图就会分成下面的四个子序列:
子序列1:

子序列2:

子序列3:

子序列4:

对每个子序列进行直接插入排序,使得每个子序列都有序,然后再组合成新的数组如下:

第二次分解排序
继续对上面数组分成子序列,比如第二次以间隔3(即增量为3)分成若干子序列,颜色相同的为一个子序列:

对每个子序列直接插入排序然后组合成新序列为(由于巧合,分解后的每个子序列都有序,所以组合后和第一步组合后的数组一样):

第三次分解排序
把第二次分解排序后的数组分成子序列,比如第三次以间隔2(即增量为2)分成若干子序列,那么分解后的子序列为:

如上图,红色为一个子序列,紫色为一个子序列,对这两个子序列分别进行直接插入排序,然后数组变成如下图:

第四分解排序
我们增量为1,那么第一个和第二个…一直到最后一个,整个数组是一个子序列,对其进行直接插入排序。此时数组已经接近有序了,所以此时插入排序会更接近O(n)。

总结:不难看出,思想很巧妙,而且一开始的时候,交换次数会多,到后面越来越有序,调用直接插入排序时,时间复杂度也越来越接近O(n)。其实我个人觉得希尔排序归并排序有异曲同工之妙。
我觉得,归并排序和希尔排序的区别就在于一开始的时候。
归并排序一开始是一个元素为一个序列,然后俩俩合并成一个有序的子序列,再俩俩子序列合并,最后生成一个有序的子序列。
希尔排序是一开始依靠增量将数组分成若干个子序列,然后将子序列排序合并(注意是在原数组上操作,实际是对下标的掌控,进而对值的掌控,在下面代码中体现出来),增量变小,继续分,继续排,增量越来越小,子序列越来越长,到最后只剩一个子序列(即增量为1),简单使用直接插入排序就完成了。

2.希尔排序的增量选择

增量increment的取法有各种方案。最初shell提出取increment=n/2向下取整,increment=increment/2向下取整,直到increment=1。但由于直到最后一步,在奇数位置的元素才会与偶数位置的元素进行比较,这样使用这个序列的效率会很低。后来Knuth提出取increment=n/3向下取整+1。还有人提出都取奇数为好,也有人提出increment互质为好。应用不同的序列会使希尔排序算法的性能有很大的差异。(此段话摘自博客为此处)

3.希尔排序代码

void ShowArr(int* arr, int len)
{for (int i = 0; i < len; ++i){printf("%d ", arr[i]);}printf("\n");
}void ShellSort(int* arr,int start,int end)
{int increment = (end - start + 1);//初始化划分增量int flg = 1;//注意:此变量对希尔排序无意义,我们这里只是为了统计数组第几次排序while(increment != 1)//划分增量==1是最后一次排序,过后数组有序,结束排序{increment = increment / 3 + 1;//划分增量每次都用上次的划分增量除以三向上取整for (int i = start + increment; i <= end; i++)//从start+increment开始,后面就是各子序列的非有序数据{int tmp = arr[i];//保存子序列未排序的部分的最左边的元素while (i - increment >= 0 && arr[i - increment] > tmp)//找非有序数据在有序数据应该放置的位置{arr[i] = arr[i - increment];i = i - increment;//间隔increment的数据才为同一个子序列的数据,所以找子序列元素需要跳着找 }arr[i] = tmp;}printf("第%d次排序、增量为%d后数组:\n", flg++,increment);ShowArr(arr, end+1);}
}int main()
{int arr[] = { 23,34,13,25,67,74,65,42,31,13,79 };ShellSort(arr, 0, sizeof(arr) / sizeof(arr[0])-1);return 0;
}

运行结果:

观察每一次排序后数组的元素变化,和我们最开始讨论希尔排序思想过程一样。

排序算法——希尔排序(缩小增量排序)相关推荐

  1. 排序算法(四)--谢尔排序(缩小增量排序)

    由上一篇博文可知,冒泡排序时,若待排序序列长度为n,则冒泡排序法时间复杂度为O(n2).但若待排序序列已经按值有序,则其时间复杂度变为O(n).由此推想,若待排序序列按值"基本有序" ...

  2. java shell排序_八大排序算法——希尔(shell)排序

    一.动图演示 二.思路分析希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 简单插入 ...

  3. python排序算法——希尔排序(附代码)

    python排序算法--希尔排序 文章目录 python排序算法--希尔排序 一.前言 二.算法描述 三.代码实现 总结 一.前言 相关知识来自<python算法设计与分析>.初级排序算法 ...

  4. 排序算法之希尔排序(缩小增量排序)

    前面两篇介绍了两个非常简单又非常基础的算法--选择排序和插入排序,并通过一篇关于大乐透的小应用程序介绍了插入排序的一个简单应用.本篇介绍一个基于插入排序算法的.快速的排序算法--希尔排序.同样,本篇主 ...

  5. ReviewForJob——希尔排序(缩小增量排序)之塞奇威克增量序列

    [0]README 0)希尔排序是基于插入排序的.将插入排序算法 内for循环中的所有 1 改为增量就可以..bingo.. 插入排序源码 1)本文旨在给出 希尔排序(缩小增量排序)之塞奇威克增量序列 ...

  6. 数据结构之插入排序:希尔排序(缩小增量排序)

    排序算法:希尔排序.缩小增量排序 思维导图: 希尔排序的定义: 例: 希尔排序d的选取: 希尔排序的代码实现: 希尔排序的性能: 思维导图: 希尔排序的定义: 普通的插入算法正序时时间复杂度会很小,但 ...

  7. java冒泡排序_JAVA实现经典排序算法(冒泡排序、选择排序、插入排序、希尔排序、堆排序、归并排序、快速排序)...

    冒泡排序 依次比较相邻的元素,若发现逆顺序,则交换.小的向前换,大的向后换,本次循环完毕之后再次从头开始扫描,直到某次扫描中没有元素交换,说明每个元素都不比它后面的元素大,至此排序完成. import ...

  8. 希尔排序是一种稳定的排序算法_十大经典排序算法——希尔排序

    vs code ppt c++/java 目录 1.1.排序分类 1.2.排序的定义: 对一序列对象根据某个关键字进行排序. 1.3.术语说明 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的 ...

  9. 十大排序算法:冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序

    冒泡排序.选择排序.插入排序.希尔排序.归并排序.快速排序.堆排序.计数排序.桶排序.基数排序的动图与源代码. 目录 关于时间复杂度 冒泡排序 选择排序 插入排序 希尔排序 归并排序 快速排序 堆排序 ...

  10. 希尔排序是一种稳定的排序算法_排序算法—希尔排序

    希尔排序 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n ...

最新文章

  1. 无线红外探测器03-环境搭建及程序详解
  2. 科大星云诗社动态20210509
  3. 《剑指offer》旋转数组的最小数字
  4. 运行Myeclipse发生这事这是怎么回事,大神们
  5. leetcode 整数反转
  6. 计算机组成与系统结构第二版第5章,计算机组成与系统结构第五章答案.pdf
  7. ORACLE异常(整理网上资料)
  8. 编译U-boot时,make[1]: *** 没有规则可以创建mkimage.o”
  9. jieba分词怎么操作_如何运用jieba库分词
  10. [小说]魔王冢(22)启程
  11. 利用finalshell连接腾讯云服务器linux系统记录
  12. 22.3 MIDI 和音乐
  13. JAVA基于JSP的疫情学生宿舍管理系统【数据库设计、论文、源码、开题报告】
  14. 数学乐 --- 年利率与欧拉数e
  15. 基于特征点检测的人脸融合
  16. 双亲委派模型以及SpringFactoriesLoader详解(最全最简单的介绍)
  17. 【渝粤教育】广东开放大学 证券投资学 形成性考核 (1)
  18. 2021年英语四级作文
  19. 作用域和改变this指向
  20. 劲乐园合歌(幽灵圣典+飞吧喜鹊+唯一+v3+幽灵圣典2)1铃声 劲乐...

热门文章

  1. 让我们开一家医生假条商店吧/E
  2. Day11多态部分-1 【1.1 多态的体现】
  3. [LeetCode] Palindrome Number Valid Palindrome - 回文系列问题
  4. iOS之深入解析Cocoapods的工作原理与源码分析
  5. 年薪201万的华为“天才少年”曾是三本复读生,逆袭就是抓住每一次提升自己的机会
  6. 阿里面试官问我,你们的需求研发/开发流程是怎样的?我???
  7. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1041:奇偶数判断
  8. ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车超声波避障实验(有舵机)
  9. SUID + SGID + STICKY
  10. pycharm里怎么关闭一个项目_【周末分享】一个完整的项目复盘到底要怎么做?...