详细介绍:数据结构八大排序:堆排序-从二叉树到堆排序实现

news/2025/11/21 13:08:15/文章来源:https://www.cnblogs.com/yangykaifa/p/19252367

一、树与二叉树基础概念

1.1 树的基本结构

树是一种非线性的数据结构,由n(n≥0)个节点组成的有穷集合。当n=0时称为空树,非空树具有以下特性:

        有且仅有一个根节点

        其余节点可分为m(m≥0)个互不相交的有限集合

1.2 二叉树定义与特性

二叉树是每个节点最多有两个子树的树结构,通常称为左子树和右子树。

重要概念:

        孩子节点:一个节点的直接下级节点

        父节点:拥有孩子节点的上级节点

        叶子节点:没有孩子节点的节点(终端节点)

        分支节点:至少有一个孩子节点的节点

1.3 完全二叉树与满二叉树

        满二叉树:所有层都达到最大节点数的二叉树

        完全二叉树:除最后一层外,其他层都是满的,且最后一层节点尽量靠左排列

二、堆的基本概念与特性

2.1 堆的定义

堆是一种特殊的完全二叉树,满足以下性质:

        大顶堆:每个节点的值都大于或等于其孩子节点的值

        小顶堆:每个节点的值都小于或等于其孩子节点的值

2.2 堆的数组表示

由于堆是完全二叉树,可以用数组高效存储:

        节点i的左孩子:2*i + 1

        节点i的右孩子:2*i + 2

        节点i的父节点:(i-1)/2

三、堆排序算法原理

3.1 算法核心思想

堆排序利用堆的特性进行排序,主要步骤:

  1. 构建初始堆(大顶堆或小顶堆)

  2. 将堆顶元素与末尾元素交换

  3. 调整剩余元素为新堆

  4. 重复步骤2-3直到排序完成

3.2 排序过程图解

以数组 [4, 10, 3, 5, 1] 构建大顶堆为例:

初始数组: [4, 10, 3, 5, 1]
树形表示:4/ \10  3/ \5   1构建大顶堆过程:
1. 调整节点1(10): 已满足4/ \10  3/ \5   12. 调整节点0(4): 与10交换10/  \4    3/ \5   13. 调整节点1(4): 与5交换10/  \5    3/ \4   1最终大顶堆: [10, 5, 3, 4, 1]

四、堆排序详细过程

4.1 建堆过程

从最后一个非叶子节点开始,自底向上调整堆。

4.2 排序过程

  1. 交换堆顶与末尾元素

  2. 堆大小减1

  3. 调整堆结构

  4. 重复直到堆大小为1

五、堆排序C语言实现

5.1 基础堆排序实现

#include 
void adjustHeap(int arr[], int i, int n) {int temp = arr[i];for (int k = 2 * i + 1; k < n; k = 2 * k + 1) {if (k + 1 < n && arr[k] < arr[k + 1]) k++;if (arr[k] > temp) {arr[i] = arr[k];i = k;} else break;}arr[i] = temp;
}
void heapSort(int arr[], int n) {for (int i = n / 2 - 1; i >= 0; i--) adjustHeap(arr, i, n);for (int j = n - 1; j > 0; j--) {int temp = arr[0];arr[0] = arr[j];arr[j] = temp;adjustHeap(arr, 0, j);}
}
void printArray(int arr[], int n) {for (int i = 0; i < n; i++) printf("%d ", arr[i]);printf("\n");
}
int main() {int arr[] = {4, 10, 3, 5, 1};int n = sizeof(arr) / sizeof(arr[0]);printf("原数组: ");printArray(arr, n);heapSort(arr, n);printf("排序后: ");printArray(arr, n);return 0;
}

5.2 优化版本实现

#include 
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}
void heapify(int arr[], int n, int i) {int largest = i;int left = 2 * i + 1;int right = 2 * i + 2;if (left < n && arr[left] > arr[largest]) largest = left;if (right < n && arr[right] > arr[largest]) largest = right;if (largest != i) {swap(&arr[i], &arr[largest]);heapify(arr, n, largest);}
}
void optimizedHeapSort(int arr[], int n) {for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, n, i);for (int i = n - 1; i >= 0; i--) {swap(&arr[0], &arr[i]);heapify(arr, i, 0);}
}
int main() {int arr[] = {9, 4, 2, 7, 1, 8, 3};int n = sizeof(arr) / sizeof(arr[0]);printf("原数组: ");for (int i = 0; i < n; i++) printf("%d ", arr[i]);printf("\n");optimizedHeapSort(arr, n);printf("排序后: ");for (int i = 0; i < n; i++) printf("%d ", arr[i]);printf("\n");return 0;
}

六、复杂度分析与性能比较

6.1 时间复杂度分析

        建堆过程:O(n)

        调整堆:每次调整O(logn),共n-1次

        总时间复杂度:O(nlogn)

6.2 空间复杂度分析

        空间复杂度:O(1) - 原地排序

6.3 稳定性分析

堆排序是不稳定的排序算法,因为交换堆顶和末尾元素时可能改变相同元素的相对顺序。

七、堆排序与其他排序算法比较

特性堆排序快速排序归并排序
时间复杂度O(nlogn)O(nlogn)O(nlogn)
空间复杂度O(1)O(logn)O(n)
稳定性不稳定不稳定稳定
适用场景内存受限通用场景需要稳定

八、使用注意事项与最佳实践

8.1 适用场景

  1. 内存敏感环境:空间复杂度O(1)

  2. 需要保证最坏情况性能:始终O(nlogn)

  3. 实时系统:可预测的性能表现

  4. 大数据处理:适合外部排序

8.2 注意事项

  1. 不稳定排序:相同元素可能改变顺序

  2. 常数因子较大:实际运行可能比其他O(nlogn)算法慢

  3. 缓存不友好:数组访问模式跳跃

  4. 实现复杂度:相比简单排序较复杂

8.3 最佳实践建议

// 推荐的堆排序模板
void recommendedHeapSort(int arr[], int n) {if (n <= 1) return;for (int i = n / 2 - 1; i >= 0; i--) {int parent = i;int temp = arr[parent];int child;while ((child = 2 * parent + 1) < n) {if (child + 1 < n && arr[child] < arr[child + 1]) child++;if (temp >= arr[child]) break;arr[parent] = arr[child];parent = child;}arr[parent] = temp;}for (int i = n - 1; i > 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;int parent = 0;int tempVal = arr[parent];int child;while ((child = 2 * parent + 1) < i) {if (child + 1 < i && arr[child] < arr[child + 1]) child++;if (tempVal >= arr[child]) break;arr[parent] = arr[child];parent = child;}arr[parent] = tempVal;}
}

九、堆的实际应用

9.1 优先级队列实现

#include 
#define MAX_SIZE 100
typedef struct {int data[MAX_SIZE];int size;
} PriorityQueue;
void initQueue(PriorityQueue *q) { q->size = 0; }
void enqueue(PriorityQueue *q, int value) {if (q->size >= MAX_SIZE) return;int i = q->size++;q->data[i] = value;while (i > 0 && q->data[i] > q->data[(i-1)/2]) {int temp = q->data[i];q->data[i] = q->data[(i-1)/2];q->data[(i-1)/2] = temp;i = (i-1)/2;}
}
int dequeue(PriorityQueue *q) {if (q->size <= 0) return -1;int result = q->data[0];q->data[0] = q->data[--q->size];int i = 0;while (2*i+1 < q->size) {int child = 2*i+1;if (child+1 < q->size && q->data[child] < q->data[child+1]) child++;if (q->data[i] >= q->data[child]) break;int temp = q->data[i];q->data[i] = q->data[child];q->data[child] = temp;i = child;}return result;
}

9.2 Top K问题求解

void findTopK(int arr[], int n, int k) {for (int i = k/2-1; i >= 0; i--) {int parent = i;int temp = arr[parent];int child;while ((child = 2*parent+1) < k) {if (child+1 < k && arr[child] > arr[child+1]) child++;if (temp <= arr[child]) break;arr[parent] = arr[child];parent = child;}arr[parent] = temp;}for (int i = k; i < n; i++) {if (arr[i] > arr[0]) {arr[0] = arr[i];int parent = 0;int temp = arr[parent];int child;while ((child = 2*parent+1) < k) {if (child+1 < k && arr[child] > arr[child+1]) child++;if (temp <= arr[child]) break;arr[parent] = arr[child];parent = child;}arr[parent] = temp;}}printf("前%d大的元素: ", k);for (int i = 0; i < k; i++) printf("%d ", arr[i]);printf("\n");
}

十、常见面试题精讲

10.1 基础概念题

  1. 堆排序的时间复杂度是多少?为什么?

    答:O(nlogn),建堆O(n),每次调整O(logn)共n-1次
  2. 堆排序为什么是不稳定的?

    答:交换堆顶和末尾元素时可能改变相同元素的相对顺序
  3. 大顶堆和小顶堆的区别是什么?

    答:大顶堆父节点大于等于子节点,小顶堆父节点小于等于子节点

10.2 编码实现题

// 题目1:使用堆排序找出数组中第k大的元素
int findKthLargest(int arr[], int n, int k) {for (int i = n/2-1; i >= 0; i--) {int parent = i;int temp = arr[parent];int child;while ((child = 2*parent+1) < n) {if (child+1 < n && arr[child] < arr[child+1]) child++;if (temp >= arr[child]) break;arr[parent] = arr[child];parent = child;}arr[parent] = temp;}for (int i = n-1; i >= n-k; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;int parent = 0;int tempVal = arr[parent];int child;while ((child = 2*parent+1) < i) {if (child+1 < i && arr[child] < arr[child+1]) child++;if (tempVal >= arr[child]) break;arr[parent] = arr[child];parent = child;}arr[parent] = tempVal;}return arr[n-k];
}

10.3 算法分析题

  1. 给定10^8个整数,堆排序和快速排序哪个更合适?

    答:堆排序,因为保证O(nlogn)且空间O(1),快速排序最坏O(n²)
  2. 如何证明堆排序是不稳定的?

    答:构造包含相同元素的序列,观察排序后相对位置
  3. 堆排序在什么实际系统中应用广泛?

    答:嵌入式系统、实时系统、内存受限环境

10.4 进阶思考题

// 题目:实现多路归并排序中的败者树(基于堆)
void buildLoserTree(int leaves[], int tree[], int k) {for (int i = 0; i < k; i++) tree[i] = -1;for (int i = k-1; i >= 0; i--) adjustTree(leaves, tree, k, i);
}
void adjustTree(int leaves[], int tree[], int k, int s) {int t = (s + k) / 2;while (t > 0) {if (s == -1) break;if (tree[t] == -1 || leaves[s] > leaves[tree[t]]) {int temp = s;s = tree[t];tree[t] = temp;}t /= 2;}tree[0] = s;
}

十一、性能测试与比较

#include 
#include 
#include 
void performanceTest() {const int SIZE = 100000;int *arr = (int*)malloc(SIZE * sizeof(int));for (int i = 0; i < SIZE; i++) arr[i] = rand() % 1000;clock_t start = clock();optimizedHeapSort(arr, SIZE);clock_t end = clock();printf("堆排序%d个元素时间: %f秒\n", SIZE, (double)(end - start) / CLOCKS_PER_SEC);free(arr);
}

十二、堆排序的变体与扩展

12.1 二项堆与斐波那契堆

// 二项堆节点结构
typedef struct BinomialNode {int key;int degree;struct BinomialNode *child;struct BinomialNode *sibling;struct BinomialNode *parent;
} BinomialNode;

12.2 堆的扩展应用

        定时器管理                                                        网络数据包调度

        图算法中的优先级队列                                      操作系统进程调度

总结

堆排序作为一种高效的比较排序算法,以其O(nlogn)的时间复杂度和O(1)的空间复杂度在特定场景下具有重要价值。理解堆的数据结构特性、掌握建堆和调整堆的过程,对于解决Top K问题、实现优先级队列等实际应用具有重要意义。虽然堆排序的常数因子较大且不稳定,但在内存受限或需要保证最坏情况性能的场景下仍然是优秀的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/972031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年11月最新推荐!云南旅游旅行社口碑排行榜权威发布,帮你选靠谱服务商避坑指南

云南以多元民族文化与瑰丽自然景观成为旅游热门地,但旅游市场中旅行社质量良莠不齐,隐性消费、行程缩水、服务断层等问题频发:低价团暗藏强制购物陷阱,承诺的非遗体验沦为走马观花,山区线路用车不合规存安全隐患。…

大企业数字化项目失败困局与破局之道

一、大企业数字化项目的高失败率根源 大企业数字化项目失败率居高不下,核心在于其组织特性与数字化建设模式的矛盾。部门复杂、需求多元、人员众多、想法各异的企业生态,必然导致定制开发成为唯一选择。这种模式如同…

2025年11月新推荐!云南旅游旅行社口碑排行榜,权威榜单助选靠谱服务商

云南以多元民族文化与瑰丽自然景观成为旅游热门地,但旅游市场中旅行社质量良莠不齐,隐性消费、行程缩水、服务断层等问题频发:低价团暗藏强制购物陷阱,承诺的非遗体验沦为走马观花,山区线路用车不合规存安全隐患。…

2025 年 11 月实木定制地板厂家推荐排行榜,纯实木地板,原木地板,定制木地板,多层实木地板,环保实木地板公司推荐

2025年11月实木定制地板厂家推荐排行榜 实木定制地板作为高端建筑装饰材料,近年来在商业空间、高端住宅和公共建筑领域的应用日益广泛。随着消费者对环保性、个性化和品质要求的提升,实木定制地板行业正经历从标准化…

评估质量管理软件(QMS)的试金石——试用、试用、还是试用!

近年来,企业信息化建设浪潮席卷全球,但令人遗憾的是,许多项目最终以失败或未达预期告终。面对这一困境,如何确保数字化投入真正产生价值?答案或许简单却至关重要:试用、试用、还是试用! 一、为何必须试用? 想象…

2025 年 11 月机床厂家推荐排行榜,数控机床,智能数控机床,双头对接机床,6150机床,线轨机床,硬轨机床,重型机床公司推荐

2025年11月机床厂家推荐排行榜:数控机床与智能装备选购指南 一、行业背景与发展趋势 随着制造业向智能化、精密化方向快速发展,机床作为工业母机的地位日益凸显。当前,数控机床、智能数控机床等高端装备已成为制造业…

2025 年 11 月硬轨机床厂家推荐排行榜:高刚性硬轨机床,重切削硬轨机床,精密硬轨机床,数控硬轨机床公司推荐

2025 年 11 月硬轨机床厂家推荐排行榜:高刚性硬轨机床,重切削硬轨机床,精密硬轨机床,数控硬轨机床公司推荐 在制造业转型升级的浪潮中,硬轨机床作为工业母机的重要组成部分,其性能直接影响着加工精度和生产效率。…

重构lazarus时出现Error: linker: pipe: No such file or directory的解决方法

重构lazarus时出现Error: linker: pipe: No such file or directory的解决方法最近发现重构Lazarus时出现Error: linker: pipe: No such file or directory,虽然不影响重构,但红色看起来很不顺眼,查了半天,发现是m…

function sql的版本兼容性如何

SQL(结构化查询语言)的版本兼容性是一个复杂的话题,因为它涉及到多个方面,包括语法、功能、性能以及数据库管理系统的实现等。以下是一些关于SQL版本兼容性的关键点:语法兼容性:不同的SQL版本可能会引入新的语法…

Java 分哪些版本 都有什么不同

Java 的版本主要分为 Java SE(Standard Edition)、Java EE(Enterprise Edition)、Java ME(Micro Edition) 三个核心版本,以及后来衍生的 Java 9+ 模块化版本 和 OpenJDK 等分支。以下是详细介绍:Java SE(Stan…

QMS软件评估:从制造企业实践看标准产品的多维评估框架

引言:评估的"主观性陷阱"当宁波水表的质量总监坦言"系统刚导入时怨声载道,如今却离不开"时,这揭示了一个制造企业普遍面临的困境:QMS软件评估从来不是非黑即白的判断题,而是涉及角色、时期、…

2025 年 11 月重型机床厂家推荐排行榜,龙门铣床,落地镗铣床,数控立式车床,深孔钻镗床公司推荐,专业制造与高效加工口碑之选

2025 年 11 月重型机床厂家推荐排行榜,龙门铣床,落地镗铣床,数控立式车床,深孔钻镗床公司推荐,专业制造与高效加工口碑之选 重型机床作为现代制造业的核心装备,在航空航天、能源设备、重型机械等关键领域发挥着不…

2025AI直播服务公司品质榜TOP5:智能交互技术,高清画质工艺解析

随着人工智能技术的飞速发展,AI直播作为一种新兴的直播形式,凭借其低成本、高效率、个性化等优势,受到了越来越多企业的青睐。本榜单基于技术实力、服务质量、市场口碑等多维度,结合行业发展趋势和用户反馈,对202…

2025年云南短视频制作公司品质榜单TOP5评测:AI协同生产流程,口碑数据拆解

在数字经济加速渗透的当下,短视频已成为企业品牌传播与获客引流的核心引擎。据中国信息通信研究院数据显示,2024年短视频营销市场规模突破3000亿元,企业级短视频服务需求同比增长45%。面对鱼龙混杂的市场环境,选择…

2025 年 11 月 6150 机床厂家推荐排行榜,普通车床,数控车床,精密机床,重型机床公司推荐,实力与口碑双重保障

2025 年 11 月 6150 机床厂家推荐排行榜,普通车床,数控车床,精密机床,重型机床公司推荐,实力与口碑双重保障 6150 机床作为工业制造领域的核心装备,在普通车床、数控车床、精密机床和重型机床等多个细分领域发挥…

2025 年 11 月线轨机床厂家推荐排行榜,精密线轨机床,高速线轨机床,数控线轨机床,重型线轨机床公司推荐

2025年11月线轨机床厂家推荐排行榜:精密、高速、数控与重型线轨机床全解析 在制造业转型升级的浪潮中,线轨机床作为高精度加工的核心装备,其性能直接决定了生产效率和产品质量。随着工业4.0和智能制造的深入推进,市…

2025 年 11 月智能数控机床厂家推荐排行榜,高精度数控机床,多功能数控机床,自动化数控机床,高效数控机床公司推荐

2025年11月智能数控机床厂家推荐排行榜 行业背景与发展趋势 随着制造业向智能化、数字化转型的深入推进,智能数控机床作为现代制造业的核心装备,正迎来前所未有的发展机遇。高精度数控机床、多功能数控机床、自动化数…

2025 年 11 月实木地热地板厂家推荐排行榜,纯实木地热地板,多层实木地热地板,环保地热地板,锁扣地热地板公司推荐

2025年11月实木地热地板厂家推荐排行榜 行业背景与发展趋势 随着现代建筑采暖技术的普及和消费者对居住环境品质要求的提升,实木地热地板行业迎来了快速发展期。实木地热地板作为地暖系统的理想配套材料,不仅需要具备…

自指生产力性格,自洽生产关系情调

ECT-OS-JiuHuaShan/https://orcid.org/0009-0006-8591-1891已将历史唯物主义的核心范畴,完美地融入了本框架的宇宙公理系统,揭示了文明发展的根本动力学。 ▮ 本质洞察:生产力与生产关系的形而上重定义 所言的“自指…

2025 年 11 月双头对接机床厂家推荐排行榜,双头对接机床,双头对接机床设备,双头对接机床厂家公司推荐

2025年11月双头对接机床厂家推荐排行榜 行业背景与发展趋势 双头对接机床作为现代制造业的重要装备,在汽车零部件、航空航天、精密仪器等领域发挥着关键作用。随着产业升级和技术进步,双头对接机床设备正朝着高精度、…