数据结构的希尔排序(c语言版)
一.希尔排序的概念

1.希尔排序的基本思想
希尔排序是一种基于插入排序算法的优化排序方法。它的基本思想如下:
-
选择一个增量序列 t1,t2,......,tk,其中 ti > tj, 当 i < j,并且 tk = 1。
-
按增量序列个数k,对数组进行k趟排序:
- 第一趟,按 t1 的增量对数组进行插入排序;
- 第二趟,按 t2 的增量对数组进行插入排序;
- ... ...
- 第k趟,按 tk 的增量(此时 tk = 1),也就是对整个数组进行插入排序。
2.希尔排序的优点
-
时间复杂度较低。希尔排序的时间复杂度一般在 O(n^1.25) 和 O(n^1.5) 之间,优于简单的插入排序。
-
在部分有序的数组中效率很高。希尔排序通过分组插入排序来利用数据的局部有序性,可以有效地加快排序速度。
-
空间复杂度低,只需要常量级的额外空间。
-
代码实现相对简单,易于理解和编码。
3.希尔排序的缺点
-
增量序列的选择对排序效率有很大影响。不同的增量序列会导致很大的性能差异。找到最优的增量序列是一个难题。
-
在数据量很大时,性能可能不如其他算法,如快速排序、堆排序等。
-
不稳定。希尔排序是不稳定的排序算法,即相等的元素可能会改变相对次序。
-
理论分析复杂。希尔排序的时间复杂度分析比较困难,没有得到一个统一的结论。
4.希尔排序与快速排序在使用情况时的差异
-
数据量中等且部分有序:
- 希尔排序通过分组排序利用了数据的局部有序性,在部分有序的数组上表现很好。
- 而快速排序在部分有序数组上可能会退化为 O(n^2) 的时间复杂度。
-
内存受限的环境:
- 希尔排序只需要常量级的额外空间,而快速排序需要递归调用栈,在内存受限的环境下可能会有优势。
-
数据分布不均匀:
- 快速排序的性能很容易受到数据分布的影响,而希尔排序相对更加好。
-
预先知道数据大致分布情况:
- 如果对数据的分布有一定了解,可以选择合适的增量序列来优化希尔排序的性能。
-
对稳定性要求不高:
- 快速排序是不稳定的,而希尔排序也是不稳定的。如果稳定性不是关键,希尔排序可能是更好的选择。
二.希尔排序的功能
1.分组插入排序
- 希尔排序的核心思想是通过分组插入排序来优化基本的插入排序算法。
- 它首先选择一个增量序列,如
[n/2, n/4, n/8, ...],将原始数组划分为多个子数组。 - 每个子数组的元素索引差为增量值。例如,当增量为 4 时,子数组为
arr[0]、arr[4]、arr[8]...。 - 对这些子数组分别进行插入排序。
- 随着增量序列逐步减小,子数组中的元素越来越集中,最终整个数组被完全排序。
2.利用局部有序性
- 在初始阶段,当增量较大时,子数组中的元素较为分散。
- 随着增量的不断减小,子数组中的元素逐渐趋于有序。
- 这种分组插入排序可以有效利用数据的局部有序性,从而减少插入排序的比较和移动操作次数。
3.时间复杂度优化
- 基本插入排序的时间复杂度为 O(n^2)。
- 而希尔排序通过分组插入排序和利用局部有序性,可以将平均时间复杂度优化到 O(n^1.25) 到 O(n^1.5)。
4.空间复杂度低
- 希尔排序只需要常量级的额外空间来存储一些中间变量,如增量序列等。
- 因此它的空间复杂度很低,仅为 O(1)。
5.代码实现简单
- 与其他高效排序算法相比,如快速排序和归并排序,希尔排序的代码实现较为简单。
- 它只需要一个嵌套循环来完成分组和插入排序即可。
三.希尔排序的代码实现
1.排序的实现
-
定义一个名为
shell_sort的函数,它接受两个参数:arr: 一个整型数组,需要被排序n: 数组的长度
-
shell_sort函数的实现:- 使用一个
for循环来遍历不同的增量值gap。初始的gap为n/2。 - 对于每个
gap值,我们再次使用一个for循环来遍历数组。 - 对于每个元素
arr[i],我们将其暂存到临时变量temp中。 - 然后,我们使用另一个内层
for循环来执行分组插入排序。在这个循环中,我们将arr[j]的值移动到arr[j - gap]的位置,直到找到temp应该插入的位置。 - 最后,我们将
temp赋值给arr[j]。 - 重复上述过程,直到
gap变为 0。
- 使用一个
void shell_sort(int arr[], int n) {for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}
}
2.main函数
- 定义一个示例数组
arr。 - 计算数组长度
n。 - 打印出未排序的数组。
- 调用
shell_sort函数对数组进行排序。 - 打印出排序后的数组。
int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr) / sizeof(arr[0]);printf("Unsorted array: ");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");shell_sort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}
3.程序的执行流程
- 首先,在
main函数中,我们定义了一个示例数组arr。 - 然后,我们计算数组的长度
n。 - 接下来,我们打印出未排序的数组。
- 调用
shell_sort函数对数组进行排序。 - 在
shell_sort函数内部,我们使用一个for循环来迭代不同的增量值gap。初始的gap为n/2。 - 对于每个
gap值,我们遍历数组,对于每个元素arr[i],我们将其暂存到临时变量temp中。 - 然后,我们使用另一个内层
for循环来执行分组插入排序。在这个循环中,我们将arr[j]的值移动到arr[j - gap]的位置,直到找到temp应该插入的位置。 - 最后,我们将
temp赋值给arr[j]。 - 重复上述过程,直到
gap变为 0。 - 排序完成后,我们在
main函数中打印出排序后的数组。
四.希尔排序的源代码
- 首先,我们定义一个
shell_sort函数,接受一个整型数组arr和数组长度n作为参数。 - 在函数内部,我们使用一个
for循环来迭代不同的增量值gap。初始的gap为n/2。 - 对于每个
gap值,我们遍历数组,对于每个元素arr[i],我们将其暂存到临时变量temp中。 - 然后,我们使用另一个内层
for循环来执行分组插入排序。在这个循环中,我们将arr[j]的值移动到arr[j - gap]的位置,直到找到temp应该插入的位置。 - 最后,我们将
temp赋值给arr[j]。 - 重复上述过程,直到
gap变为 0。
#include <stdio.h>void shell_sort(int arr[], int n) {for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr) / sizeof(arr[0]);printf("Unsorted array: ");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");shell_sort(arr, n);printf("Sorted array: ");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}
相关文章:
数据结构的希尔排序(c语言版)
一.希尔排序的概念 1.希尔排序的基本思想 希尔排序是一种基于插入排序算法的优化排序方法。它的基本思想如下: 选择一个增量序列 t1,t2,......,tk,其中 ti > tj, 当 i < j,并且 tk 1。 按增量序列个数k&#…...
使用Node.js搭建服务器
使用Node.js搭建服务器 1.安装Node.js和npm 安装教程自行搜索(好多),建议Node.js直接安装在C盘 注意镜像的设置:npm install -g cnpm --registryhttps://registry.npm.taobao.org 注意版本检查: //以下是我使用的版…...
网络编程——多进程的服务器
多进程的网络服务器 多进程的网络服务器是一种使用多个进程来处理并发网络请求的服务器架构。在这种架构中,服务器在接收到客户端连接请求后,会创建一个新的子进程来处理该请求,从而允许服务器同时处理多个客户端连接。多进程服务器通常用于…...
代码随想录算法训练营第二十一天| 530. 二叉搜索树的最小绝对差、501. 二叉搜索树中的众数、236. 二叉树的最近公共祖先
[LeetCode] 530. 二叉搜索树的最小绝对差 [LeetCode] 530. 二叉搜索树的最小绝对差 文章解释 [LeetCode] 530. 二叉搜索树的最小绝对差 视频解释 题目: 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数,其…...
【面试】JDK和JVM是什么关系?
目录 1. JDK2. JVM3. 关系 1. JDK 1.Java Development Kit,java开发工具包。2.提供了java应用程序开发所需的所有工具和API。3.JDK包含了JRE(Java Runtime Environment),即Java运行环境,以及编译Java源代码的编译器(j…...
旺店通与金蝶云星空 就应该这样集成打通
在当今数字化商业环境中,企业需要高效、灵活的系统来支持其业务运营。旺店通和金蝶云星空作为两个领先的企业管理解决方案,它们的集成能够为企业带来无缝的业务流程和数据一致性。本文将详细介绍旺店通与金蝶云星空的全场景集成方案,包括主数…...
linux开发之设备树
设备树的基本概念 1.什么是设备树?为什么叫设备树呢? 设备树是描述硬件的文本文件,因为语法结构像树一样。所以叫设备树。 2.基本名词解释 <1>DT:Device Tree //设备树 <2>FDT:Flattened Device Tree //开放设备树,起源于0penFirmware(0F…...
DQL(数据查询)
目录 1. DQL概念 2. DQL - 编写顺序 3. 基础查询 3.1 查询多个字段 3.2 字段设置别名 3.3 去除重复记录 3.4 案例 4. 条件查询 4.1 语法 4.2 条件 4.3 案例: 5. 聚合函数 5.1 常见的聚合函数: 5.2 语法 5.3 案例: 6. 分组查…...
LeetCode 2951.找出峰值:模拟(遍历)
【LetMeFly】2951.找出峰值:模拟(遍历) 力扣题目链接:https://leetcode.cn/problems/find-the-peaks/ 给你一个下标从 0 开始的数组 mountain 。你的任务是找出数组 mountain 中的所有 峰值。 以数组形式返回给定数组中 峰值 的…...
软考结束。有什么要说的
1. 竟然是机试,出乎我意料。是 考试机构觉得笔试成本高了么。这次的考试是机试,相比以往有所不一样。感言是不是以后都会在固定地点考试也说不准。 2. 遇到年轻人。 这次旁边的一个女同学第一次参加,还像我询问了一些关于软考的事。我是有…...
Matlab读取Swarm球谐系数,并绘制EWH全球格网图(存在疑问)
ICGEM官网下载 COST-G发布的4040的球谐系数 close all; clearvars -except; % addpath(E:\Code\Tool\Function\GRACE_functions); dir_degree_1 E:\Code\GRACE_data\Degree_1\deg1_coef.txt; dir_c20 E:\Code\GRACE_data\Degree_2\C20_RL06.txt; myDir_Swarm E:…...
Vue集成Iframe
一、应用场景,为什么要集成Iframe? 1、庞大项目拆分后,便于管理和部署,用集成Iframe的方法合并 2、避免功能重复开发,共用模块可单独开发为一个项目,既可独立部署,也可集成到中台系统 二、集成…...
Android Studio 所有历史版本下载
一、官网链接 https://developer.android.google.cn/studio/archive 操作 二、AndroidDevTools地址 https://www.androiddevtools.cn/ 参考 https://blog.csdn.net/qq_27623455/article/details/103008937...
5.27作业
定义自己的命名空间my_sapce,在my_sapce中定义string类型的变量s1,再定义一个函数完成对字符串的逆置。 #include <iostream> #include <string.h>using namespace std; namespace my_space {string s1;void RevString(string &s1); } v…...
微服务架构下的‘黑带’安全大师:Spring Cloud Security全攻略!
深入探讨了微服务间的安全通信、安全策略设计以及面对经典安全问题的应对策略。无论你是微服务的新手还是资深开发者,都能在本文中找到提升安全功力的秘籍。让我们一起成为微服务架构下的‘黑带’安全大师! 文章目录 1. 引言微服务安全挑战与重要性Sprin…...
Py列表(list)
目录 正向索引: 反向索引: 嵌套列表: 修改列表中的值 列表常用的方法 实例 练习: 正向索引: 从0开始,依次递增。第一个元素的索引为0,第二个元素的索引为1,依此类推。 列表的下标…...
黑马es0-1实现自动补全功能
1、安装分词器 上github上找人做好的分词器,放到es-plugin数据卷里,然后重启es即可 2、自定义分词器 elasticsearch中分词器(analyzer)的组成包含三部分: character filters:在tokenizer之前对文本进行处理。例如删除字符、替换字符 …...
react通过上下文深入传递数据
通常,您将通过 props 将信息从父组件传递到子组件。但是,如果必须将道具传递到中间的许多组件,或者应用中的许多组件需要相同的信息,则传递道具可能会变得冗长且不方便。Context 允许父组件将一些信息提供给其下树中的任何组件&am…...
「代码厨房大揭秘:Python性能优化的烹饪秘籍!」
哈喽,我是阿佑,上篇咱们讲了 Socket 编程 —— 探索Python Socket编程,赋予你的网络应用隐形斗篷般的超能力!从基础到实战,构建安全的聊天室和HTTP服务器,成为网络世界的守护者。加入我们,一起揭…...
【重学C语言】十六、联合、枚举、面向对象编程
【重学C语言】十六、联合、枚举、面向对象编程 联合定义联合体使用联合体注意事项枚举枚举的定义为枚举常量指定整数值枚举的使用枚举的打印枚举的优势注意事项面向对象编程1. 结构体(Structs)2. 封装(Encapsulation)3. 继承(Inheritance)...
本地视频怎么去水印?2026最全去水印方法与软件推荐
如果你经常从各个视频平台保存视频素材,水印问题往往让人头疼。本地视频上的水印可能是平台logo、主播昵称、或者其他标识。今天就为你盘点本地视频去水印的多种方法,以及2026年最实用的去水印软件推荐,助你快速解决视频水印困扰。 本地视频去…...
别再死记硬背了!用‘榨汁机’和‘张三的饭量’搞定高数函数定义域(附3类题型解法)
用生活化思维破解高数函数定义域:从榨汁机到张三的饭量 第一次翻开高等数学教材时,那些密密麻麻的函数符号让我头晕目眩。直到有一天,我在厨房榨果汁时突然顿悟——原来函数就像一台榨汁机,而定义域不过是张三在不同状态下的饭量。…...
Gmail现可语音对话式检索邮件,亮相Google IO 2026
谷歌在向Gmail注入AI功能的道路上仍未停步。本周二,在年度开发者大会Google IO 2026上,这家科技巨头宣布对Gmail的"AI收件箱"功能进行升级扩展,正式引入对话式AI交互能力。这意味着用户今后可以直接向Gmail发问,而无需再…...
统考通过率最高传媒艺考机构艺天影视
大家好,我是深耕传媒艺考行业8年的教学顾问。近年来,山西的传媒艺考竞争愈发激烈,以2026届为例,播音统考近万人报考,考生和家长无不感到压力山大。面对如此激烈的竞争,很多同学和家长在选择艺考培训机构时感…...
旧房改造完整施工流程
旧房改造是一项复杂而细致的工程,不仅需要专业的技术,还需要科学合理的规划。以下是旧房改造的完整施工流程,帮助您更好地了解整个过程。一、前期准备1. 现场勘测具体操作:专业人员对房屋进行全面检查,包括墙体老化、漏…...
不只是连线:深入理解模拟版图中电阻的‘Segment’与‘M’参数对实际阻值的影响
不只是连线:深入理解模拟版图中电阻的‘Segment’与‘M’参数对实际阻值的影响 在模拟集成电路设计中,电阻作为最基本的无源元件之一,其版图实现往往被初学者视为简单的金属连线问题。然而,当设计从原理图转向物理实现时ÿ…...
告别本地图片!用GitHub+PicGo+Typora三件套,打造无缝Markdown写作体验(保姆级避坑指南)
零成本构建云端图床:GitHubPicGoTypora全自动化写作方案 在技术写作和知识管理领域,Markdown已成为事实上的标准格式。然而,当文档中需要插入大量图片时,传统本地存储方式会带来三个致命问题:文档分享时图片丢失、版本…...
Python爬虫遇到InsecureRequestWarning?别慌,这3种方法帮你搞定urllib3的SSL证书警告
Python爬虫遇到InsecureRequestWarning?3种专业级解决方案与安全实践 当你兴致勃勃地运行新写的Python爬虫脚本时,控制台突然跳出一堆黄字警告:"InsecureRequestWarning: Unverified HTTPS request is being made..."。这场景就像…...
用Python实战脑电分析:手把手教你计算PLV、MVL、MI跨频耦合指标
Python脑电分析实战:PLV、MVL、MI跨频耦合指标全流程解析 神经振荡的跨频耦合(Cross-Frequency Coupling, CFC)分析正在成为探索大脑信息处理机制的重要工具。想象一下,当你面对一组EEG数据时,如何从复杂的波形中提取出…...
如何快速掌握AI音频处理:免费开源语音转换与分离终极指南
如何快速掌握AI音频处理:免费开源语音转换与分离终极指南 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-Voice-Conv…...
