数据结构-希尔排序
1、希尔排序
也称 递减增量排序算法,是 插入排序 的一种更高效的改进版本。希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
-
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到 线性排序 的效率;
-
但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。
步长的选择是希尔排序的重要部分。
只要最终步长为1任何步长序列都可以工作。
算法最开始以一定的步长进行排序。
然后会继续以一定步长进行排序,最终算法以步长为1进行排序。
当步长为1时,算法变为普通插入排序,这就保证了数据一定会被排序。
插入排序的算法步骤如下:
-
定义一个用来分割的步长;
-
按步长的长度K,对数组进行K趟排序;
-
不断重复上述步骤。
简单插入排序很循规蹈矩,不管数组分布是怎么样的,依然一步一步的对元素进行比较,移动,插入,比如[5,4,3,2,1,0]这种倒序序列,数组末端的0要回到首位置很是费劲,比较和移动元素均需n-1次。
而希尔排序在数组中采用跳跃式分组的策略,通过某个增量将数组元素划分为若干组,然后分组进行插入排序,随后逐步缩小增量,继续按组进行插入排序操作,直至增量为1。
希尔排序通过这种策略使得整个数组在初始阶段达到从宏观上看基本有序,小的基本在前,大的基本在后。
然后缩小增量,到增量为1时,其实多数情况下只需微调即可,不会涉及过多的数据移动。
#include <stdio.h> void InsertSort(int* p, int n) { int temp,i,j; for (i = 0; i < n; i++) { temp = p[i]; for (j = i - 1; (j >= 0) && (p[j] > temp); j--) { p[j + 1] = p[j]; } p[j + 1] = temp; } } void ShellInsertSort(int* p, int n) { int temp, i, j; int gap = n; do { gap = gap / 3 + 1; //对步长进行操作,包括不同步长下的循环,直到步长为1时 for (i = gap; i < n; i++) { if (p[i] < p[i - gap]) //这里是一个小技巧,判断当前是否有序,在无序的情况下才需要插入操作! { temp = p[i]; //设置哨兵,就是要插入的元素 for (j = i - gap; (j >= 0) && (p[j] > temp); j-=gap) //j为哨兵前一个需要比较的元素 { p[j + gap] = p[j]; } p[j + gap] = temp; } } } while (gap>1); } int main() { int a[] = { 4,2,5,6,7,8,3,1,9 }; ShellInsertSort(a,9); printf_s("排序后:\n"); for (int i = 0; i < 9; i++) { printf_s("%d ", a[i]); } return 1; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧