《大话数据结构》第9章精读:希尔排序与堆排序完整 C++ 实现 1. 引言从简单排序到高效排序简单排序冒泡、直接插入、简单选择的平均时间复杂度都是 O(n²)当数据量增大时效率明显不足。《大话数据结构》第9章接下来介绍了两种重要的改进算法希尔排序插入排序的改进和堆排序选择排序的改进。本文基于《大话数据结构》第9章内容结合《C Primer Plus》的编程视角给出两种算法的完整 C 实现、复杂度分析、对比表格与测试代码方便直接复制运行。2. 希尔排序Shell Sort2.1 核心思想把数组按一定增量gap分组对每组进行直接插入排序。随着增量逐渐减小数组越来越接近有序最后一趟增量变为 1 时就是普通的插入排序。希尔排序通过“跳跃式”的比较与移动大幅减少了插入排序中元素的移动次数。下图展示了希尔排序的分组与跳跃式移动过程2.2 完整实现常用 Knuth 序列#include iostream #include vector using namespace std; void ShellSort(vectorint arr) { int n arr.size(); // 使用 Knuth 序列gap gap * 3 1 int gap 1; while (gap n / 3) { gap gap * 3 1; } while (gap 1) { // 对每个分组进行插入排序 for (int i gap; i n; i) { int key arr[i]; int j i; while (j gap arr[j - gap] key) { arr[j] arr[j - gap]; j - gap; } arr[j] key; } gap / 3; // 缩小增量 } }2.3 复杂度与特点指标说明平均时间复杂度约 O(n^1.3) O(n^1.5)取决于增量序列最坏时间复杂度O(n²)空间复杂度O(1)稳定性不稳定优点实现简单对中等规模数据表现较好代码开销小。3. 堆排序Heap Sort3.1 核心思想利用堆这种数据结构。先把数组建成大顶堆此时堆顶是最大值把它与末尾元素交换然后把剩余部分重新调整为堆重复此过程。堆排序是选择排序的高效改进时间复杂度稳定在 O(n log n)。下图展示了大顶堆的建堆与交换过程3.2 完整实现// 调整以 index 为根的子树使其符合大顶堆 void heapify(vectorint arr, int n, int index) { int largest index; // 假设当前节点最大 int left 2 * index 1; // 左孩子 int right 2 * index 2; // 右孩子 if (left n arr[left] arr[largest]) { largest left; } if (right n arr[right] arr[largest]) { largest right; } // 如果最大值不是当前节点就交换并继续向下调整 if (largest ! index) { swap(arr[index], arr[largest]); heapify(arr, n, largest); } } void HeapSort(vectorint arr) { int n arr.size(); // 1. 建堆从最后一个非叶子节点开始向前调整 for (int i n / 2 - 1; i 0; --i) { heapify(arr, n, i); } // 2. 排序每次把堆顶最大值换到末尾再调整剩余部分 for (int i n - 1; i 0; --i) { swap(arr[0], arr[i]); // 堆顶与末尾交换 heapify(arr, i, 0); // 调整剩余元素 } }3.3 复杂度与特点指标说明时间复杂度最好、平均、最坏都是 O(n log n)空间复杂度O(1)原地排序稳定性不稳定特点建堆时间是 O(n)非常高效。适合大数据量且不需要额外内存。4. 两种算法对比对比维度希尔排序堆排序时间复杂度约 O(n^1.3)O(n log n) 稳定空间复杂度O(1)O(1)稳定性不稳定不稳定实现难度较低中等需要理解堆调整适用场景中等数据量、代码简单要求大数据量、要求时间稳定是否原地排序是是5. 完整测试代码#include iostream #include vector using namespace std; void printArray(const vectorint arr) { for (int x : arr) cout x ; cout endl; } int main() { vectorint arr1 {49, 38, 65, 97, 76, 13, 27, 49, 55, 4}; vectorint arr2 arr1; cout 原数组; printArray(arr1); ShellSort(arr1); cout 希尔排序后; printArray(arr1); HeapSort(arr2); cout 堆排序后; printArray(arr2); return 0; }运行结果原数组49 38 65 97 76 13 27 49 55 4 希尔排序后4 13 27 38 49 49 55 65 76 97 堆排序后4 13 27 38 49 49 55 65 76 976. 总结与思考希尔排序通过增量分组打破了插入排序只能移动相邻元素的限制显著提升了效率。堆排序把“每次选最值”的思想用堆结构高效实现时间复杂度稳定在 O(n log n)。结合《C Primer Plus》的思考堆排序中的 heapify 是典型的递归思想对应书中对递归与树形结构的讲解。两种算法都做到了原地排序体现了“空间效率优先”的设计。下一篇将讲解第9章最经典的两种高效排序归并排序和快速排序。

相关新闻

最新新闻

设备出海非洲却频频掉线?选对物联网卡才能让业务跑起来

设备出海非洲却频频掉线?选对物联网卡才能让业务跑起来

中非经贸合作正在加速升温。南非是中国在非洲的第一大贸易伙伴,2025年双边贸易额达535.8亿美元;尼日利亚2025年对华进口规模达249.1亿美元,居非洲首位;埃及、肯尼亚、埃塞俄比亚同样位列中国在非洲的五大贸易伙伴之列。越来越多的…

2026/8/25 15:54:48
头歌实践教学平台:数据科学与大数据技术导论(五)

头歌实践教学平台:数据科学与大数据技术导论(五)

五、数据科学导论——数学基础之概率第1关:概率基础之贝叶斯任务描述 本关任务:根据相关知识,完成与数据概率相关的选择题。相关知识 我们可以把概率论视为从事件空间中抽取的事件的不确定性进行量化的一种方式。空间是指所有可能的结果的集合…

2026/8/25 15:54:48
RFID固定资产管理系统,让企业资产管控全面数字化

RFID固定资产管理系统,让企业资产管控全面数字化

几乎所有企业都会遇到同一个管理难题:资产越用越乱、台账越记越虚、盘点越盘越累。无论是政企单位、工厂车间、学校医院,还是酒店物业、工程项目,企业固定资产数量多、分布散、流转快、周期长。传统依靠Excel台账、纸质登记、人工盘点的管理方…

2026/8/25 15:54:48
高频因子IC衰减实战从因子构建到有效性检验的本地化Python全流程 IG50免费开源股票数据API接口

高频因子IC衰减实战从因子构建到有效性检验的本地化Python全流程 IG50免费开源股票数据API接口

高频因子 IC 衰减实战:从因子构建到有效性检验的本地化 Python 全流程 做量化研究这几年,**IC 衰减(IC Decay)**是评估因子有效性的核心工具之一。大部分研究员的认知里"IC 越高、因子越好",但当我把所有 A…

2026/8/25 15:54:48
【895My.CoM】魔域发布网来源玩法介绍大全【魔域】魔域技术

【895My.CoM】魔域发布网来源玩法介绍大全【魔域】魔域技术

一、 魔域游戏简介魔域是一款经典的魔幻题材大型多人在线角色扮演游戏(MMORPG),以其宏大的世界观、丰富的职业体系、独特的幻兽养成系统和激烈的军团战玩法而闻名。玩家将在亚特大陆上扮演一名冒险者,通过战斗、任务和社交不断成长…

2026/8/25 15:54:48
深入浅出TinyML 15:时域特征能够描述信号的哪些属性?

深入浅出TinyML 15:时域特征能够描述信号的哪些属性?

时域特征把一段波形压缩成少量数字。均值描述基线,RMS描述总体能量,峰峰值描述幅度范围,峭度对尖锐冲击更敏感。特征名称熟悉并不代表它一定适合当前任务。有效特征应在类别之间形成稳定差异,并在设备、温度和时间变化下保持可重复…

2026/8/25 15:49:47