千家信息网

c语言中如何实现堆排序

发表于:2025-02-03 作者:千家信息网编辑
千家信息网最后更新 2025年02月03日,这篇文章给大家介绍c语言中如何实现堆排序,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。堆是一棵顺序存储的完全二叉树。其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小
千家信息网最后更新 2025年02月03日c语言中如何实现堆排序

这篇文章给大家介绍c语言中如何实现堆排序,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。


堆是一棵顺序存储的完全二叉树。
其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆。
其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆。
举例来说,对于n个元素的序列{R0, R1, … , Rn}当且仅当满足下列关系之一时,称之为堆:
(1) Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)
(2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)
其中i=1,2,…,n/2向下取整;

如上图所示,序列R{3, 5, 8, 10, 7}是一个典型的小根堆。
堆中有两个父结点,元素3和元素8。
元素3在数组中以R[0]表示,它的左孩子结点是R[1],右孩子结点是R[2]。
元素5在数组中以R[1]表示,它的左孩子结点是R[3],右孩子结点是R[4],它的父结点是R[0]。可以看出,它们满足以下规律:
设当前元素在数组中以R[i]表示,那么,
(1) 它的左孩子结点是:R[2i+1];
(2) 它的右孩子结点是:R[2i+2];
(3) 它的父结点是:R[(i-1)/2];
(4) R[i] <= R[2i+1] 且 R[i] <= R[2i+2]。
首先,按堆的定义将数组R[0..n]调整为堆(这个过程称为创建初始堆),交换R[0]和R[n];
然后,将R[0..n-1]调整为堆,交换R[0]和R[n-1];
如此反复,直到交换了R[0]和R[1]为止。
以上思想可归纳为两个操作:
(1)根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。
(2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。
当输出完最后一个元素后,这个数组已经是按照从小到大的顺序排列了。
先通过详细的实例图来看一下,如何构建初始堆。
设有一个无序序列 { 1, 3, 4, 5, 2, 6, 9, 7, 8, 0 }。

构造了初始堆后,我们来看一下完整的堆排序处理:
还是针对前面提到的无序序列 { 1, 3, 4, 5, 2, 6, 9, 7, 8, 0 } 来加以说明。

相信,通过以上两幅图,应该能很直观的演示堆排序的操作处理。
代码:

#include #include void    HeapAdjust(int *array, int parent, int length);void    printPart(int *array, int begin, int end);int main(){    int array[10] = {1, 3, 4, 5, 2, 6, 9, 7, 8, 0};    int length = (sizeof(array) / sizeof(int));    for (int i = length / 2 ; i >= 0; i--)    {        HeapAdjust(array, i, length);    }    for (int i = length - 1; i > 0; i--)     {        // 最后一个元素和第一元素进行交换        int temp = array[i];        array[i] = array[0];        array[0] = temp;        // 筛选 array[0] 结点,得到i-1个结点的堆        HeapAdjust(array, 0, i);        printf("第 %d 趟: \t", length - i);        printPart(array, 0, length - 1);    }    system("pause");    return 0;}void    HeapAdjust(int *array, int parent, int length){    int tmp = array[parent];    int Lchild = 2 * parent + 1;    while (Lchild= array[Lchild])            break;        // 把孩子结点的值赋给父结点        array[parent] = array[Lchild];        // 选取孩子结点的左孩子结点,继续向下筛选        parent = Lchild;        Lchild = 2 * Lchild + 1;    }    array[parent] = tmp;}void printPart(int *array, int begin, int end){    for (int i = begin; i <= end; i++)     {        printf("%d \t",array[i]);    }    printf("\n");}

关于c语言中如何实现堆排序就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

结点 孩子 元素 数组 排序 关键 关键字 序列 大根 小根 调整 语言 两个 内容 更多 顺序 处理 帮助 输出 不错 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 数据库的数据是如何使用的 北京卓网络技术有限公司 怎么删除微信数据库文件 软件开发奖惩制度怎么制定模板 广州即合互联网络科技有限公司 网络安全法的实施时间及意义 mysql查看数据库日志 刀塔2服务器 巨杉数据库生产环境 c 动态创建数据库表 联想服务器管理工具 网络安全政府主管企业主责 福建移动公司网络安全部雷佳 宽带卡显示服务器错误 关系数据库主要特点的叙述 导入数据库sql语句 软件开发专业实训心得 数据库事务完整性 哪里招网络技术人员吗 水务行业数据库备份技术原理 新华三紫光存储服务器 数据库的记录集 备份sql数据库表数据库 网络安全法的实施时间及意义 软件开发服务费发票可以写套吗 我的世界服务器的作用是什么 海康闸机终端服务器 网络安全理智追星手抄报 网络安全周网络安全小课堂 数据库连接怎么实现数据增删改查
0