当前位置: 首页 > news >正文

二叉树中堆的数据结构

堆的概念和结构

如果有一个关键码的集合K = {k1 ,k2 ,k3 ,…,kn },把它的所有元素按完全二叉树的顺序存储方式存储
在一个一维数组中,(i为下标)并满足:ki <= k(2i+1)且 ki<= k(2i+2)(ki >=k(2i+1) 且 ki>=k(2i+2) ) i = 0,1,2…,则称为小堆(或大堆)。将根结点最大的堆叫做最大堆或大根堆,根结点最小的堆叫做最小堆或小根堆。
堆的性质:

  • 堆中某个结点的值总是不大于或不小于其父结点的值;
  • 堆总是一棵完全二叉树。

下面是大堆的示例图:

堆的代码实现

//堆的初始化voidHpInit(Hp*php){assert(php);php->a=NULL;php->size=php->capacity=0;}//堆的销毁voidHpDestroy(Hp*php){assert(php);php->a=NULL;php->size=php->capacity=0;}//交换函数voidSwap(int*p1,int*p2){inttmp=*p1;*p1=*p2;*p2=tmp;}//向上调整voidAdjustUp(HpData*a,intchild){assert(a);intparent=(child-1)/2;while(child>0){if(a[child]<a[parent]){Swap(&a[child],&a[parent]);child=parent;parent=(child-1)/2;}else{break;}}}//堆的插入(向上调整版)voidHpPush(Hp*php,HpData x){assert(php);if(php->capacity==php->size){intnewcapacity=php->capacity==0?4:2*php->capacity;HpData*tmp=(int*)realloc(php->a,newcapacity*sizeof(HpData));if(tmp==NULL){perror("realloc fail!");return;}php->a=tmp;php->capacity=newcapacity;}php->a[php->size]=x;php->size++;AdjustUp(php->a,php->size-1);}// 堆数据的打印voidHpPrint(Hp*php){for(inti=0;i<php->size;i++){printf("%d ",php->a[i]);}printf("\n");}//向下调整voidAdjustDown(HpData*a,intparent,intsize){assert(a);intchild=2*parent+1;while(child<size){if(child+1<size&&a[child]>a[child+1]){child++;}if(a[child]<a[parent]){Swap(&a[child],&a[parent]);parent=child;child=2*parent+1;}else{break;}}}//堆的插入(向下调整版)voidHpPush2(Hp*php,HpData x){assert(php);if(php->capacity==php->size){intnewcapacity=php->capacity==0?4:2*php->capacity;HpData*tmp=(int*)realloc(php->a,newcapacity*sizeof(HpData));if(tmp==NULL){perror("realloc fail!");return;}php->a=tmp;php->capacity=newcapacity;}php->a[php->size]=x;php->size++;AdjustDown(php->a,0,php->size);}//判空boolHpEmpty(Hp*php){if(php->a==NULL){returntrue;}else{returnfalse;}}//取堆顶数据HpDataHpTop(Hp*php){assert(php);returnphp->a[0];}//删除堆顶voidHpPop(Hp*php){Swap(&php->a[0],&php->a[php->size-1]);php->size--;AdjustDown(php->a,0,php->size);}

堆排序

通过上面的介绍,我们已经了解了堆是如何实现的,以及如何建立大堆和小堆
所以接下来我们可以通过上面完成的向上和向下调整建堆来实现堆排序

//向上调整建堆voidHpSort1(){intarr[]={4,6,1,7,9,8,2,5};//降序 先建小堆for(inti=0;i<sizeof(arr)/sizeof(int);i++){AdjustUp(arr,i);}intend=sizeof(arr)/sizeof(int)-1;while(end>0){Swap(&arr[0],&arr[end]);AdjustDown(arr,0,end);end--;}for(inti=0;i<sizeof(arr)/sizeof(int);i++){printf("%d ",arr[i]);}}//向下调整建堆voidHpSort2(){intarr[]={4,6,1,7,9,8,2,5};intn=sizeof(arr)/sizeof(int);intend=n;for(inti=(n-1-1)/2;i>=0;i--){AdjustDown(arr,i,n);}while(end>0){Swap(&arr[0],&arr[end-1]);AdjustDown(arr,0,end-1);--end;}for(inti=0;i<sizeof(arr)/sizeof(int);i++){printf("%d ",arr[i]);}}intmain(){HpSort1();printf("\n");HpSort2();return0;}


我们这里实现的是降序排序

代码解析

首先我们两个代码都是进行建立小堆,然后将堆顶(最小的数)与堆末尾的数据交换,再进行向上或向下调整,这样又把第二小的数放在了堆顶,而我们使用了–end,使得最小的数永远留在了堆末尾,然后依次循环,又不断地将次小的数据置在堆顶,并与下标为end的数据交换再进行调整,从而实现降序排序。

注意事项

向下调整建堆时间复杂度是 O (n),向上调整是 O (n log n),所以一般使用向下调整建堆
向上调整建堆:

  • 从第 0 个元素开始,一个个插入堆
  • 每插入一个,都要向上走到根,最多走 树高 h = log₂n
  • 总共 n 个节点
  • 复杂度:O(n log n)

向下调整建堆:

  • 只调整非叶子节点
  • 从倒数第二层开始往前调
  • 越靠近底层的节点,需要向下走的步数越少
  • 复杂度:O(n)
http://www.jsqmd.com/news/600365/

相关文章:

  • 2026年热门的非标热压机优质公司推荐 - 品牌宣传支持者
  • Flutter OH 外接纹理第一帧(背景)自定义
  • OpenClaw+千问3.5-35B-A3B-FP8:自动化代码审查助手
  • Dynamic Voxelization目标检测环境配置、Dynamic Voxelization目标检测模型代跑训练、Dynamic Voxelization目标检测模型改进创新Dynamic
  • 从命令到思想:Shell脚本编程的“一课一得”
  • OpenClaw安全实践:千问3.5-27B本地化部署的3重防护
  • 汽车电子MISRA C编码规范详解与实践
  • 笑晕!复刻《伪装者》名场面,程序员版身份暴击太真实了
  • 如何在Jetson Orin nano上安装lerobot 和与之兼容的pytorch GPU
  • OpenClaw文件管理:Qwen3-4B驱动的智能归类与重命名
  • 从芯片手册到飞控上天:揭秘ArduPilot硬件抽象层(HAL)与hwdef.dat的协作机制
  • DIY必备:如何用PW4053芯片打造三节锂电池充电模块(附电路图)
  • SCNet Faster R-CNN Transfer Learning Object Detection PASCAL VOC实例
  • AI生成代码的安全雷区
  • 2026年靠谱的高密度纤维水泥板/广州装饰纤维水泥板/广州通体色纤维水泥板/装饰纤维水泥板实力厂家推荐 - 品牌宣传支持者
  • 成本透明化:OpenClaw执行Qwen3-4B任务的Token消耗监控
  • GridPlayer:多视频同步播放的终极解决方案
  • 2026年口碑好的锻件/大型锻件生产厂家推荐 - 品牌宣传支持者
  • 为什么说现在99%的视频AI都是“伪智能”?问题根本不在模型,而在“没有空间”
  • 深度剖析:如何通过NiPruned技术实现Stable Diffusion模型40%显存优化的实战指南
  • 2026四川防爆检测优质机构推荐指南 - 优质品牌商家
  • 2026年口碑好的偏轴门系统/重型轴门系统优质供应商推荐 - 品牌宣传支持者
  • 2026成都餐饮厨房设备回收公司推荐指南 - 优质品牌商家
  • Wireshark Statistics模块保姆级实战:从协议分析到网络排障的完整指南
  • 用SDNET2018和Crack500数据集训练YOLOv8,手把手教你搞定混凝土裂缝检测模型
  • Ubuntu系统将本地文件夹上传至服务器
  • html 列表和表格的使用
  • 2026年化工行业自动压滤机优质推荐指南 - 优质品牌商家
  • 2026年评价高的沸石转轮参数/烟尘净化设备/沸石转轮RTO/废气治理设备公司精选 - 品牌宣传支持者
  • Flowable任务超时监控与自动化处理实战