【数据结构】堆的实现

news/2024/10/26 16:25:58/

目录

  • 堆的概念
  • 堆的结构声明
  • 堆的初始化
  • 插入数据
  • 移除数据
  • 打印

堆的概念

堆总是一个完全二叉树。
大堆:树中一个树及子树中,任何一个父亲都大于等于孩子。
小堆:树中一个树及子树中,任何一个父亲都小于等于孩子。

大堆
在这里插入图片描述
我们可以看到 75比 60 和 70 大, 60 比 55 和 40 大,也就是树中任何一个父亲都大于或等于孩子,所以这是一个大堆。

小堆
在这里插入图片描述
而任何一个父亲都小于或等于孩子,这就是小堆。那么接下来我们来实现一个大堆。

堆的结构声明

那么我们用什么结构来实现堆呢?用链表和数组都可以,但是数组比较方便查找,所以我们这里用数组来实现一个堆。
在这里插入图片描述
所以堆的结构类似于我们的顺序表。

typedef int HeapDataType;typedef struct Heap
{HeapDataType* data;size_t sz;size_t Cacpcity;
}HP;

堆的初始化

让data指向空,数组长度和容量置为0

void HeapInit(HP* hp)
{hp->data = NULL;hp->sz = hp->Cacpcity = 0;
}

插入数据

因为有大堆和小堆的区分,所以数据的插入也会有所差异。因此我们这里实现大堆,那么就要保证树中父亲必须大于等于孩子。

那么再插入的时候,我们必须让孩子和它的父亲比较。

在这里插入图片描述
如图我们可以发现, 40 和 45的下标为 3 , 4 ,它们父亲 60的下标为1。

那我们可以总结出一个公式,父亲的下标 = (孩子的下标-1) / 2。

比如 60的下标是 1 , 40的下标是 3 , 那么 (3-1)/2 = 1, 比如 55的下标是2, 75的下标是 0 , ( 2 - 1 ) / 2 = 0。

而我们插入的时候,必须要和父亲比较,在大堆的情况下,孩子是不可能比父亲大的。

比如我要在 55的下面插入一个 80
在这里插入图片描述
我们称这个过程为向上调整。

//检查容量
void CheckCacpcity(HP* hp)
{if (hp->Cacpcity == hp->sz){//扩容size_t newCacpcity = hp->Cacpcity == 0 ? 4 : 2 * hp->Cacpcity;//扩容HP* newhp = realloc(hp->data, sizeof(HeapDataType) * newCacpcity);if (newhp == NULL){printf("realloc fail\n");exit(-1);}hp->data = newhp;hp->Cacpcity = newCacpcity;}
}//向上调整
void AdjustUp(HP* hp, int child)
{//至少比较一次do{int parent = (child - 1) / 2;//如果父亲小于孩子if (hp->data[parent] < hp->data[child]){//交换HeapDataType tmp = hp->data[child];hp->data[child] = hp->data[parent];hp->data[parent] = tmp;//更新childchild = parent;}else{break;}} while (child > 0);}void HeapPush(HP* hp, HeapDataType x)
{assert(hp);//先判断容量是否够用CheckCacpcity(hp);//插入数据hp->data[hp->sz] = x;hp->sz++;//向上调整AdjustUp(hp, hp->sz - 1);
}

移除数据

因为完全二叉树最后一层必须是连续的,所以我们直接 移除最后一个数据即可。


void HeapPop(HP* hp)
{assert(hp);hp->sz--;
}

打印

为了方便观察,我们再打印一下。

void HeapPrint(HP* hp)
{for (int i = 0; i < hp->sz; i++)printf("%d ", hp->data[i]);printf("\n");
}

随后 我们再插入一个大于父亲的数据试试效果。我们插入一个77。
在这里插入图片描述

在这里插入图片描述
我们就会发现,77和75调换位置了。实际上变成了这样。
在这里插入图片描述
堆的实现我们就讲到这里了,堆只是二叉树的一个小部分,后续会给大家分享更多关于二叉树的知识,感谢大家支持。代码已上传至git,点击此处获取


http://www.ppmy.cn/news/3014.html

相关文章

计算机网络—session、cookie

文章目录cookiesessioncookie session token&#xff1a;————————————————————————————————Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式&#xff0c; 但是两者的应用场景不太一样。 cookie Cookie 一般用来保存用户信息 。比如&…

Pytest框架批量安装插件解析

1、新建一个工程 使用新的环境变量 1.1.插件文件 新建一个txt的文件&#xff0c;将常用插件放在该文件中&#xff0c;如下图 文件名&#xff1a;requirements.txt 常用插件&#xff1a; pytest pytest-html pytest-xdist pytest-ordering pytest-rerunfailures allure-pyt…

C++类设计和实现的十大最佳实践

C代码提供了足够的灵活性&#xff0c;因此对于大部分工程师来说都很难把握。本文介绍了写好C代码需要遵循的10个最佳实践&#xff0c;并在最后提供了一个工具可以帮助我们分析C代码的健壮度。原文&#xff1a;10 Best practices to design and implement a C class 1. 尽可能尝…

Android调用JNI的实现方法

目录概述调用JNI接口的方法后记概述 Android调用JNI库大致包括两种情况&#xff1a; 提供Java接口和so库&#xff1a; 这种类型的调用比较简单&#xff0c;要做的只是把so库放到APK或者Android系统中&#xff0c;之后在使用的时候调用对应的Java接口就行。JNI部分的代码提供商…

【SpringMVC】上篇,超详细的教程带你学会SpringMVC

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;【Spring】 &#x1f96d;本文内…

二、基础平滑、面积折线图与折线堆叠、面积堆叠《手把手教你 ECharts 数据可视化详解》

注&#xff1a;本系列教程需要对应 JavaScript 、html、css 基础&#xff0c;否则将会导致阅读时困难&#xff0c;本教程将会从 ECharts 的官方示例出发&#xff0c;详解每一个示例实现&#xff0c;从中学习 ECharts 。 ECharts 官方示例&#xff1a;https://echarts.apache.o…

【C语言】函数递归详解

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​ &#x1f4e3;系列专栏&#xff1a;鹏哥带我学c带我飞 &#x1f4ac;总结&#xff1a;希望你看…

java版商城多商家入驻商城 直播带货商城 电子商务

一个好的SpringCloudSpringBoot b2b2c 电子商务平台涉及哪些技术、运营方案&#xff1f;以下是我结合公司的产品做的总结&#xff0c;希望可以帮助到大家&#xff01; 搜索体验小程序&#xff1a;海哇 1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家…