【C++】神秘-希尔排序
插入排序
在待排序的元素中,假设前k个元素已有序,现将第k+1个元素插入到前面已经排好的序列中,使得前k个元素有序。
按照此法对所有元素进行插入,直到整个序列有序。
但我们并不能确定待排元素中究竟哪一部分是有序的。,
所以我们一开始只能认为第一个元素是有序的,依次将其后面的元素插入到这个有序序列中来,直到整个序列有序为止。

↑↑↑黑色圈住的数字表示要插入到前面序列的数字
希尔排序
讲完插入排序,就该讲我们的重点了。
希尔排序是一种改进的插入排序算法,也被称为缩小增量排序。
它通过将待排序序列分割成多个子序列来进行排序,然后逐步缩小子序列的长度,最终使整个序列变为有序。
希尔排序的核心思想是将相距某个增量的元素组成一个子序列,对子序列进行插入排序。
然后逐步减小增量,重复上述过程,直到增量为1时,完成最后一次插入排序,使整个序列成为有序的。
希尔排序的优点
效率较高:对于大规模数据集,希尔排序通常比简单插入排序更快,特别是在处理近乎有序的数据时,由于跳跃式的比较和交换,效率提升显著。
灵活性:希尔排序通过调整间隔序列来适应不同类型的数据分布,这使得它在某些情况下能获得更好的性能,尽管没有一种固定的间隔序列适合所有场景。
稳定性:虽然希尔排序本质上不是稳定的排序算法,但在某些实现版本中,如果对相等元素进行特殊处理,可以保持相对位置不变,表现为某种形式的稳定性。
易于理解:作为一种改进的插入排序,希尔排序的原理相对直观,容易学习和实现。
然而,希尔排序的主要缺点在于它的时间复杂度依赖于所选的间隔序列,不稳定性和最坏情况下的效率不高可能会限制它在一些高并发环境下的使用。
因此,在实际应用中需要权衡性能和代码实现复杂性。
时间复杂度
希尔排序的时间复杂度取决于增量序列的选取, 一般最好情况下为O(nlogn),最坏情况下为O(n^2)。
希尔排序是 不稳定的排序算法 ,即可能改变相同元素的原始顺序。
希尔排序的思想
希尔排序也被称为缩小增量排序。
其基本思想是将待排序的元素按照一定的间隔分组,对每组使用插入排序算法进行排序,
然后逐步缩小间隔,再进行排序,直至间隔为1时进行最后一次排序。(如图)

在希尔排序中,我们要引入gap(间隔):

当gap不为1时,我们可以把它看做为一个预排序,先把数组变得比较有序。
然后当 gap为1时 就是直接 插入排序了。
因为插入排序对比较有序的数组排列效率更高,所以希尔排序就为先预排序,再直接插入排序。
预排序
我们先定义一个长度为5的逆序数组{5,4,3,2,1},再来假设gap为3。
知周所众 众所周知插入排序再排逆序的数组时,时间复杂度为最坏的情况。 所以我们才要进行预排序。


经过预排序后数组,已经变得比较有序了,这对后面的直接插入排序是有好处的,提高效率。
Knuth增量序列
Knuth增量序列是希尔排序中使用的一种增量序列,它可以保证gap最后一定为1,
它的计算方式为:
gap = 1, 3, 9, 27, ...
其中gap的初始值为1,然后每次计算下一个增量值h时,都乘以3再加1,直到h大于等于数组长度的三分之一
Knuth增量序列的特点是在每次排序中能够更好地减少逆序对的数量,从而提高排序的效率。
该增量序列的选择是经验性的,并没有严格的数学证明,但在实践中已经被广泛接受,并被证实在大多数情况下都能够有效地改善希尔排序的性能
代码实现希尔排序
下面是使用实现希尔排序的代码:
#include<iostream>
using namespace std;
const int N = 1e6+5;
int n,arr[N];
void shellSort() {
int gap = 1;// 使用Knuth增量序列,gap = 1, 3, 9, 27, ...
while (gap < n/3) gap = 3 * gap + 1;// 使用Knuth增量序列,保证gap最后为1
while (gap >= 1) {// 逐步缩小增量直到1
// 对每个子序列进行插入排序
for (int i = gap; i < n; i++)
for (int j = i; j >= gap && arr[j] < arr[j-gap]; j -= gap) swap(arr[j], arr[j-gap]);
gap /= 3;// 缩小增量
}
}
int main() {
cin>> n;
for(int i=0;i<n;i++) cin>> arr[i];
shellSort();// 排序
// 输出
for (int i = 0; i < n; i++) cout << arr[i] << " ";
return 0;
}
该代码使用了Knuth增量序列,h的初始值为数组长度的一半,然后逐渐减小h的值。
在每次循环内部,对每个子序列使用插入排序算法进行排序。最后输出排序后的数组。
总的来说,希尔排序可以应用于各种排序问题,并且在大规模数据下具有较好的性能。
【C++】神秘-希尔排序的更多相关文章
- 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)
本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...
- 希尔排序(java)
时间复杂度为O( n^(3/2) )不是一个稳定的排序算法 如何看一个算法是否稳定:{("scala",12),("python",34),("c++ ...
- Html5 希尔排序演示
希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本. 如下图所示: 代码如下: <!DOCTYPE html> <html& ...
- 浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析之后续补充说明(有图有真相)
如果你觉得我的有些话有点唐突,你不理解可以想看看前一篇<C++之冒泡排序.希尔排序.快速排序.插入排序.堆排序.基数排序性能对比分析>. 这几天闲着没事就写了一篇<C++之冒泡排序. ...
- 希尔排序及希尔排序java代码
原文链接:http://www.orlion.ga/193/ 由上图可看到希尔排序先约定一个间隔(图中是4),然后对0.4.8这个三个位置的数据进行插入排序,然后向右移一位对位置1.5.9进行插入排序 ...
- 冒泡排序 & 选择排序 & 插入排序 & 希尔排序 JavaScript 实现
之前用 JavaScript 写过 快速排序 和 归并排序,本文聊聊四个基础排序算法.(本文默认排序结果都是从小到大) 冒泡排序 冒泡排序每次循环结束会将最大的元素 "冒泡" 到最 ...
- 希尔排序(Shell)
希尔排序的实质就是分组插入排序,该方法又称缩小增量排序. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序, ...
- 希尔排序(c++)
希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于1959年提出而得名. 希尔排序是把记 ...
- JavaScript排序算法——希尔排序
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- IOS- 快速排序,冒泡排序,直接插入排序和折半插入排序,希尔排序,堆排序,直接选择排序
/*******************************快速排序 start**********************************///随即取 当前取第一个,首先找到第一个的位置 ...
随机推荐
- Go语言自定义类型
Go语言与C/C++类似,C++可通过typedef关键字自定义数据类型(别名.定义结构体等),Go语言则通过type关键字可实现自定义类型的实现 1.自定义类型格式 用户自定义类型使用type,其语 ...
- Django中图片不显示
很多教程没教对,导致Django中的图片不能正确的显示出来,经过多次踩坑,发现如下方法可以解决该问题. 1.setting.py中添加: STATIC_URL = '/static/' STATICF ...
- MAC系统13.2,安装最新版logi options+,打开一直转圈
我联系官网客服,按照他给的步骤成功的安装了options+,你试试 请抽出时间按照下面列出的故障排除步骤尝试解决问题. 卸载我们所有的软件 删除剩余文件 步骤 1:打开 Finder,在菜单栏中选择& ...
- .NET 9中的异常处理性能提升分析:为什么过去慢,未来快
一.为什么要关注.NET异常处理的性能 随着现代云原生.高并发.分布式场景的大量普及,异常处理(Exception Handling)早已不再只是一个冷僻的代码路径.在高复杂度的微服务.网络服务.异步 ...
- TinyVue 智能组件库:基于 MCP 协议,实现 AI 代替人操作 Web 组件
你好,我是 Kagol,个人公众号:前端开源星球. 2025年6月21日,我在华为开发者大会2025(HDC2025)开源论坛做了一场主题分享,给开发者们介绍我们 OpenTiny 团队基于 MCP ...
- 数栈 × AWS EMR On EC2 适配实践:打造出海企业可落地的云上数据中台解决方案
随着袋鼠云全面推进数栈产品的出海战略,我们在服务多个头部出海客户的过程中发现,真正做好"海外可用"的数据平台,关键不仅在于部署全球化,还在于深入适配 AWS 的核心计算平台EMR, ...
- git ---多用户管理
一.概述 相信大家都遇到过这样的问题,实际开发中需要在一台PC上用到 不同平台git的账号甚至同一个平台的多个账号(比如本人gitee .字自己在nas上搭建的gitea ,另外还有github账 ...
- ui-router 路由重定向
$urlRouterProvider .when('/c?id', '/contacts/:id') .when('/user/:id', '/contacts/:id') .otherwise('/ ...
- 冲刺 CSP 联训模拟2
题面 温馨提示 代码中的变量名可能与题意.题解不同. 代码不删缺省源,可以直接拿来对拍. T1 挤压 Solution 众所周知,异或是一种按位运算,不好进行十进制的数间合并.我们考虑将每个数拆分为二 ...
- 云筑集采研发团队的Scrum敏捷实践总结
Edison作为团队内部敏捷教练,这是我正式辅导的第一个Scrum Master童鞋(花名:大师兄)的敏捷迭代实践总结,在互联网公司做敏捷转型,难而正确! Scrum 是用于开发.交付和持续支持复杂产 ...