news 2026/5/1 7:20:01

堆的定义与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
堆的定义与实现

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、堆的定义
  • 二、堆的实现
    • 1.大/小堆的构建
    • 2.堆的增删查

前言


一、堆的定义

结构基础:堆是基于完全二叉树的逻辑结构,用数组来物理实现。

核心性质:堆可分为大堆和小堆。
其中,大堆要求每个子树的父节点>=左右子节点。
小堆要求每个子树的父节点 <= 左右子节点。

//堆用C实现typedefintHPDataType;typedefstructHeap{HPDataType*_a;//堆元素的存放数组int_size;//有效元素个数int_capacity;//容量}Heap;

二、堆的实现

为什么堆可以用数组来实现?

因为数组可以实现快速的随机访问,操作更加简单。再加上完全二叉树不会浪费很多数组的空间。

1.大/小堆的构建

(以小堆为例)
为了让最小的数在堆顶,其余的小数都在其子树的父亲节点。
要用到“向下调整”的算法。来调整根节点和两子树的关系,是根保持为最小。

当parent = n, 左 child = 2 * n + 1, 右child = 2 * n + 2 基于数组实现的索引规律
//参数分别为 堆中元素(数组),元素总个数,需要向下调整的父亲节点voidAdjustdowm(HPDataType*a,intn,introot){intparent=root;intchild=2*parent+1;//先假设左孩子while(child<n)//结束条件:孩子节点不能大于总数{if(child<n&&a[child]>a[child+1]){child++;//右孩子小,使child走到右孩子}//如果孩子节点小于父亲节点if(a[child]<a[parent]){swap(&a[child],&a[parent]);parent=child;child=parent*2+1;}else{break;}}}

但向下调整的前提是单前节点的左右子树都是(小)堆,才能保证拿上来的是最小值。
所以要从最后一个节点的父亲节点开始向下调整,由下到上。

当孩子child = n时,parent = (n-1) /2 最后一个孩子是n-1, 得出最后一个父亲是(n-1-1)/2
//构建堆——以小堆为例for(inti=(n-1-1)/2;i>=0;i--)//从最后一个节点的父亲节点开始,从下往上才能保证左右子树都是小堆{AdjustDown(hp->_a,hp->_size,i);}

2.堆的增删查

如何在堆中增加一个数,而不破坏小堆的形式?
先把数据加在末尾,再使用向上调整算法,使数据到合适的地方。

//向上调整---(以小堆为例)AdjustUp(HPDataType*a,intn,intchild){intparent=(child-1)/2;while(child>0)//当child = 0时,才算调整完{if(a[child]<a[parent]){swap(&a[child],&a[parent]);child=parent;parent=(child-1)/2;}else{break;}}}

增加一个元素

// 堆的插入voidHeapPush(Heap*hp,HPDataType x){//插入时只能先在末尾插入,再调整到堆中合适的地方if(hp->_size==hp->_capacity){hp->_capacity*=2;HPDataType*tmp=(HPDataType*)realloc(hp->_a,sizeof(HPDataType)*hp->_capacity);if(tmp!=NULL){hp->_a=tmp;}else{printf("扩容失败");}}hp->_a[hp->_size++]=x;//需要将插入值向上调整AdjustUp(hp->_a,hp->_size,hp->_size-1);}

删堆顶的数据,是先将堆顶与数组最后一个元素交换,再删除最后一个元素,将新元素向下调整。
因为最后一个元素方面删除。

// 堆的删除——(肯定删的是堆顶的数据)voidHeapPop(Heap*hp){intend=hp->_size-1;if(end<0){return;}else{swap(&hp->_a[0],&hp->_a[end]);hp->_size--;AdjustDown(hp->_a,hp->_size,0);}}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 8:16:35

使用记事本编写运行Java程序,零基础小白到精通,收藏这篇就够了

一、编写Java源程序 Java 源程序可以使用任何一个文本编辑器来编写&#xff0c;这里以 Windows 下的记事本为例。 (1) 新建一个空白记事本&#xff0c;然后如实地输入下列内容。 很多初学者可能不明白此程序的全部意义&#xff0c;没关系&#xff0c;请完全按照实例的样式输入…

作者头像 李华
网站建设 2026/4/29 19:18:38

一文读懂_CTF:网络安全领域的_“实战练兵场”,新手入门全

收藏必备&#xff01;CTF全解析&#xff1a;从定义到6大题型&#xff0c;小白程序员入门网络安全的实战指南 本文全面解析CTF(Capture The Flag)竞赛&#xff0c;介绍其作为网络安全实战训练的本质与价值。详细阐述CTF两种比赛形式(Jeopardy攻防答题赛和Attack-Defense攻防对抗…

作者头像 李华
网站建设 2026/4/30 10:32:38

零基础入门_CTF_全攻略:从靶场练手到赛事夺冠,附工具_

【强烈收藏】小白学CTF&#xff1a;网络安全实战学习路径与避坑指南 CTF是网络安全入门的最佳实战载体&#xff0c;适合零基础新手、在校学生和职场人。文章提供三阶段学习路径&#xff1a;基础搭建期&#xff08;1-2个月&#xff09;掌握Linux、Python和网络协议&#xff1b;…

作者头像 李华
网站建设 2026/4/17 23:46:38

灰盒测试在软件开发中的关键应用场景与价值探索

1 灰盒测试的核心定位与价值 灰盒测试作为介于黑盒测试与白盒测试之间的重要测试方法&#xff0c;既关注外部功能表现&#xff0c;又结合内部结构知识进行验证。其核心价值在于突破传统测试方法的局限&#xff1a;通过有限度的代码逻辑知晓&#xff08;如API接口结构、数据库表…

作者头像 李华
网站建设 2026/4/21 5:47:06

保姆级教程:大模型学习指南(零基础入门到项目实战),建议收藏_AI大模型神仙级入门教程(非常详细)

这篇文章为AI大模型初学者提供全面入门指南&#xff0c;包括理解大模型基础、准备软硬件环境、学习机器学习与深度学习知识、使用预训练模型、进行模型微调以及参与实战项目。文章详细介绍了从初阶应用到模型训练再到商业闭环的学习路径&#xff0c;帮助读者系统掌握大模型技术…

作者头像 李华