C++数据结构之堆的概念是什么
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,今天小编给大家分享一下C++数据结构之堆的概念是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起
千家信息网最后更新 2025年11月07日C++数据结构之堆的概念是什么
今天小编给大家分享一下C++数据结构之堆的概念是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
堆的概念
堆(heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象,即是一种顺序储存结构的完全二叉树。
提示:完全二叉树
完全二叉树:对一棵深度为k、有n个结点二叉树编号后,各节点的编号与深度为k的满二叉树相同位置的结点的编号相同,这颗二叉树就被称为完全二叉树。[2]
堆的性质
堆中某个结点的值总是不大于或不小于其父结点的值
堆总是一棵完全二叉树
除了根结点和最后一个左子结点可以没有兄弟结点,其他结点必须有兄弟结点
最大堆最小堆
最大堆:根结点的键值是所有堆结点键值中最大者,且每个结点的值都比其孩子的值大。
最小堆:根结点的键值是所有堆结点键值中最小者,且每个结点的值都比其孩子的值小。
代码
定义
有限数组形式
int Heap[1024]; //顺序结构的二叉树
若某结点编号为i,且存在左儿子和右儿子,则他们分别对应
Heap[i*2+1]; //左儿子Heap[i*2+2]; //右儿子
其父节点
Heap[i/2]; //i的父节点
动态数组形式
在项目开发中,经常以动态数组形式出现,在本文主要对这种形式进行介绍
//默认容量#define DEFAULT_CAPCITY 128typedef struct _Heap{ int *arr; //储存元素的动态数组 int size; //元素个数 int capacity; //当前存储的容量 }Heap;操作
只使用InitHeap()函数进行初始化即可,AdjustDown()与BuildHeap()仅为堆建立时的内部调用
向下调整结点
以创建最大堆为例
将"判断最大子结点是否大于当前父结点"处的>=改为<=即可创建最小堆
//向下调整,将当前结点与其子结点调整为最大堆//用static修饰禁止外部调用static void AdjustDown(Heap& heap, int index){ int cur = heap.arr[index]; //当前待调整结点 int parent, child; /* 判断是否存在子结点大于当前结点。 若不存在,堆是平衡的,则不调整; 若存在,则与最大子结点与之交换,交换后该子节点若还有子结点,则以此方法继续调整。 */ for (parent = index; (parent * 2 + 1) < heap.size; parent = child) { child = parent * 2 + 1; //左子结点 //取两个子结点中最大节点,(child+1)= heap.arr[child]) //将此处的>=改成<=可构建最小堆 { //不大于,不需要调整 break; } else { //大于,则交换 heap.arr[parent] = heap.arr[child]; heap.arr[child] = cur; } }} 建立堆
//建立堆,用static修饰禁止外部调用static void BuildHeap(Heap& heap){ int i; //从倒数第二层开始调整(若只有一层则从该层开始) for (i = heap.size / 2 - 1; i >= 0; i--) { AdjustDown(heap, i); }}初始化
//初始化堆//参数:被初始化的堆,存放初始数据的数组, 数组大小bool InitHeap(Heap &heap, int *orginal, int size){ //若容量大于size,则使用默认量,否则为size int capacity = DEFAULT_CAPCITY>size?DEFAULT_CAPCITY:size; heap.arr = new int[capacity]; //分配内存,类型根据实际需要可修改 if(!heap.arr) return false; //内存分配失败则返回False heap.capacity = capacity; //容量 heap.size = 0; //元素个数置为0 //若存在原始数组则构建堆 if(size>0) { /* 内存拷贝,将orginal的元素拷贝到堆数组arr中 size*sizeof(int)为元素所占内存空间大小 */ memcpy(heap.arr,orginal, size*sizeof(int)); heap.size = size; //调整大小 BuildHeap(heap); //建堆 } return true;}打印堆
实际上是一个层序遍历[4]
//以树状的形式打印堆void PrintHeapAsTreeStyle(Heap hp){ queue que; int r = 0; que.push(r); queue temp; while (!que.empty()) { r = que.front(); que.pop(); if (r * 2 + 1 < hp.size) temp.push(r * 2 + 1); if (r * 2 + 2 < hp.size) temp.push(r * 2 + 2); if (que.empty()) { cout << hp.arr[r] << endl; que = temp; temp = queue(); } else cout << hp.arr[r] << " "; }} 测试
main函数
int main(){ Heap hp; int vals[] = { 1,2,3,87,93,82,92,86,95 }; if (!InitHeap(hp, vals, sizeof(vals) / sizeof(vals[0]))) { fprintf(stderr, "初始化堆失败!\n"); exit(-1); } PrintHeapAsTreeStyle(hp); return 0;}结果
9593 9287 1 82 386 2
完整代码
#include#include using namespace std;//默认容量#define DEFAULT_CAPCITY 128typedef struct _Heap { int* arr; int size; int capacity;}Heap;//向下调整,将当前结点与其子结点调整为最大堆static void AdjustDown(Heap& heap, int index){ int cur = heap.arr[index]; //当前待调整结点 int parent, child; /* 判断是否存在子结点大于当前结点。 若不存在,堆是平衡的,则不调整; 若存在,则与最大子结点与之交换,交换后该子节点若还有子结点,则以此方法继续调整。 */ for (parent = index; (parent * 2 + 1) < heap.size; parent = child) { child = parent * 2 + 1; //左子结点 //取两个子结点中最大节点,(child+1) = heap.arr[child]) //将此处的>=改成<=可构建最小堆 { //不大于,不需要调整 break; } else { //大于,则交换 heap.arr[parent] = heap.arr[child]; heap.arr[child] = cur; } }}//建立堆,用static修饰禁止外部调用static void BuildHeap(Heap& heap){ int i; //从倒数第二层开始调整(若只有一层则从该层开始) for (i = heap.size / 2 - 1; i >= 0; i--) { AdjustDown(heap, i); }}//初始化堆//参数:被初始化的堆,存放初始数据的数组, 数组大小bool InitHeap(Heap& heap, int* orginal, int size){ //若容量大于size,则使用默认量,否则为size int capacity = DEFAULT_CAPCITY > size ? DEFAULT_CAPCITY : size; heap.arr = new int[capacity]; //分配内存,类型根据实际需要可修改 if (!heap.arr) return false; //内存分配失败则返回False heap.capacity = capacity; //容量 heap.size = 0; //元素个数置为0 //若存在原始数组则构建堆 if (size > 0) { /* 内存拷贝,将orginal的元素拷贝到堆数组arr中 size*sizeof(int)为元素所占内存空间大小 */ memcpy(heap.arr, orginal, size * sizeof(int)); heap.size = size; //调整大小 BuildHeap(heap); //建堆 } return true;}//以树状的形式打印堆void PrintHeapAsTreeStyle(Heap hp){ queue que; int r = 0; que.push(r); queue temp; while (!que.empty()) { r = que.front(); que.pop(); if (r * 2 + 1 < hp.size) temp.push(r * 2 + 1); if (r * 2 + 2 < hp.size) temp.push(r * 2 + 2); if (que.empty()) { cout << hp.arr[r] << endl; que = temp; temp = queue (); } else cout << hp.arr[r] << " "; }}int main(){ Heap hp; int vals[] = { 1,2,3,87,93,82,92,86,95 }; if (!InitHeap(hp, vals, sizeof(vals) / sizeof(vals[0]))) { fprintf(stderr, "初始化堆失败!\n"); exit(-1); } PrintHeapAsTreeStyle(hp); return 0;}
以上就是"C++数据结构之堆的概念是什么"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。
结点
调整
数组
元素
内存
容量
节点
最大
大小
形式
数据
结构
最小
大堆
儿子
拷贝
知识
篇文章
分配
数据结构
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库设计 原则
数据库关联关系错误
安全上网审计服务器
gis创建数据库的作用
永健互联网科技
网络安全你我有责黑板报
网络安全大会致辞
toad 如何添加数据库
数据库取出字符语句
绍兴软件开发驻场哪里好
温州企业进销存软件开发
计算机网络安全的概念和意义
我的世界黑客把迷你服务器弄爆了
东城区信息网络技术服务怎么样
网络技术类直播哪个平台好
服务器闪电什么意思
服务器安全狗病毒库
教师网络安全会议记录
服务器自建异地组网
如何引入金蝶帐套数据库
软件开发类面试题
河阳娄成武网络安全
松江区品质数据库价钱
家用网吧服务器
scum加入服务器连接丢失
芯片软件开发就业前景
网络安全篇网络交友
宣化区网络安全教育日
服务器安全狗病毒库
蓬莱ios软件开发外包公司