堆的实现(堆的插入、堆的删除等)超级全

堆的实现(堆的插入、堆的删除等)超级全

在这里插入图片描述

文章目录

  • 堆的实现(堆的插入、堆的删除等)超级全
    • 一、前期基础知识
      • 1.树结构
        • ①树的定义
        • ②树的相关概念
        • ③二叉树
        • ④满二叉树和完全二叉树
          • a.满二叉树
          • b.完全二叉树
        • ⑤二叉树的性质
        • ⑥二叉树顺序结构的存储和链式结构的存储
          • a.顺序结构存储
          • b.链式结构存储
      • 2.堆结构
    • 二、堆结构/二叉树顺序结构存储的实现
      • 1.堆的初始化
      • 2.堆的销毁
      • 3.堆的插入
      • 4.堆的删除
      • 5.取堆顶数据
      • 6.堆的数据个数
      • 7.堆的判空

一、前期基础知识

1.树结构

①树的定义

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

②树的相关概念

在这里插入图片描述
节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A的为6。
叶节点或终端节点:度为0的节点称为叶节点; 如上图:B、C、H、I…等节点为叶节点。
非终端节点或分支节点:度不为0的节点; 如上图:D、E、F、G…等节点为分支节点。
树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6。
节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推。
树的高度或深度:树中节点的最大层次; 如上图:树的高度为4。
n个结点的树,有n-1条边。

一棵树有以下三部分组成
根节点,无前驱结点。
叶结点,度为0,又称终端结点
非终端节点,分支节点,度不为0

一棵树是由根节点和n颗子树构成的,子树一定不能相交,除了根节点外,每一个结点都有且仅有一个父节点。

如果不是树结构,那就是图结构。

③二叉树

每一个结点的度不一定都是2,整个二叉树里不存在度大于2的结点。

  1. 或者为空
  2. 由一个根节点加上两棵别称为左子树和右子树的二叉树组成

在这里插入图片描述
在这里插入图片描述

④满二叉树和完全二叉树
a.满二叉树

满二叉树
一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是2 ^ k - 1 ,则它就是满二叉树。

b.完全二叉树

完全二叉树
前(n - 1)层是满的
最后一层不满,但是从左到右必须连续排布,最少1个,最多2 ^ (n - 1)个。

⑤二叉树的性质
  1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2 ^ (i - 1)个结点.
  2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2 ^ h - 1
  3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为n2 ,则有n0 = n2 + 1
  4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h= log2底(n + 1)。(ps: 是log以2为底,n+1为对数)
  5. 将二叉树的每一个结点按层次从0到n编号:
    0
    1 2
    3 4 5 6
    7 8 (7,8为3的子节点)
    举个例子,这就是一个完全二叉树,0 = (1 - 1) / 2, 0 = (2 - 1) / 2,所以parent = (child - 1) / 2, leftchild = parent * 2 + 1, rightchild = leftchild + 1。
    但是注意,一定要在范围里。
⑥二叉树顺序结构的存储和链式结构的存储
a.顺序结构存储

顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
在这里插入图片描述

b.链式结构存储

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,二叉链就是两个指针+数据域,三叉链就是两个指针+指向父节点+数据域,我们暂时先不做重点讲解,后续笔者会进行讲解。

2.堆结构

1.一段连续的数组数据看作完全二叉树
2.必须是小堆或者大堆
小堆:任意一个父节点小于等于子节点
大堆:任意一个父节点大于等于子节点

typedef int HPDataType;typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;

大家不妨再思考一下,数据结构的目的到底是什么,就是为了方便我们在内存中管理数据,再加上一些可以实现对这段数据进行操作的接口函数来实现我们的目的。

二、堆结构/二叉树顺序结构存储的实现

1.堆的初始化

void HPIni(HP* php)
{assert(php);php->a = NULL;php->size = 0;php->capacity = 0;
}

2.堆的销毁

void HPDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->size = 0;php->capacity = 0;
}

3.堆的插入

void Swap(HPDataType* p1, HPDataType* p2)
{assert(p1 && p2);HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}void HPAdjustUp(HPDataType* p, int child)
{assert(p);int parent = (child - 1) / 2;while (child > 0){if (p[child] < p[parent]){Swap(( & p[child]), ( & p[parent]));child = parent;parent = (parent - 1) / 2;}else{break;}}
}void HPPush(HP* php, HPDataType x)
{assert(php);if (php->size == php->capacity){int newcapacity = php->capacity == 0 ? 4 : 2 * (php->capacity);HPDataType* tmp = (HPDataType*)realloc(php->a, newcapacity * sizeof(HPDataType));if (tmp == NULL){perror("realloc");exit(-1);}php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;HPAdjustUp(php->a, (php->size - 1));
}

当你插入一个新的数据到堆里后,一定要记得你的结构实际是一个二叉树,而且以小堆为例,如果你插入的数据,比这个结点的父节点小,那就需要向上调整。

4.堆的删除

void HPAdjustDown(HP* p, int parent)
{assert(p);int child = parent * 2 + 1;//使用假设法while (child < (p->size)){if ((child + 1 < p->size) && (p->a[child + 1] < p->a[child]))//这个真的很重要,值得反复思考,进行交换{child = child + 1;}if (p->a[child] < p->a[parent]){Swap(&(p->a[child]), &(p->a[parent]));parent = child;child = child * 2 + 1;}else{break;}}
}void HPPop(HP* php)
{assert(php);assert(php->size > 0);Swap(&(php->a[0]), &(php->a[(php->size) - 1]));php->size--;HPAdjustDown(php, 0);
}

相信大家一定会有一些问题,因为堆的删除,是删除堆顶元素,大家可能会疑问,为什么不能直接头删。
原因有以下两点:
1.顺序表时间复杂度是O(N),过于复杂。
2.如果头删之后,整个数组是要向前挪一位的,整棵树的结构就全部改变了,父子关系,大小关系全部乱了,需要重新改。

所以我们重新选择一个方法,就是我们将堆顶元素和最后一个元素互换,再尾删,这样可以保证两颗子树从上到下的整个顺序都没有被改变,向下调整就只需要进入一颗子树继续调整就好啦。

5.取堆顶数据

HPDataType HPTop(HP* php)
{assert(php);assert(php->size > 0);//使用sizereturn php->a[0];
}

6.堆的数据个数

int HPSize(HP* php)
{assert(php);return (php->size);
}

7.堆的判空

bool HPEmpty(HP* php)
{assert(php);/*if (php->size == 0){return true;}else{return false;}*/return (php->size == 0);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/215715.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8改进 | 2023 | LSKAttention大核注意力机制助力极限涨点

论文地址&#xff1a;官方论文地址 代码地址&#xff1a;官方代码地址 一、本文介绍 在这篇文章中&#xff0c;我们将讲解如何将LSKAttention大核注意力机制应用于YOLOv8&#xff0c;以实现显著的性能提升。首先&#xff0c;我们介绍LSKAttention机制的基本原理&#xff0c;…

深入理解 Django 中的事务管理

概要 在数据库操作中&#xff0c;事务是确保数据完整性和一致性的关键机制。Django 作为一个强大的 Python Web 框架&#xff0c;提供了灵活而强大的事务管理功能。理解和正确使用 Django 中的事务对于开发高质量的 Web 应用至关重要。本文将深入探讨 Django 的事务管理机制&a…

2021年12月 Scratch(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 执行下列程序,屏幕上可以看到几只小猫? A:1 B:3 C:4 D:0 答案:B 第2题 下列程序哪个可以实现:按下空格键,播放完音乐后说“你好!”2秒? A: B: C:

人工智能-注意力机制之注意力汇聚:Nadaraya-Watson 核回归

查询&#xff08;自主提示&#xff09;和键&#xff08;非自主提示&#xff09;之间的交互形成了注意力汇聚&#xff1b; 注意力汇聚有选择地聚合了值&#xff08;感官输入&#xff09;以生成最终的输出。 本节将介绍注意力汇聚的更多细节&#xff0c; 以便从宏观上了解注意力机…

SpringCloud实用-OpenFeign整合okHttp

文章目录 前言正文一、OkHttpFeignConfiguration 的启用1.1 分析配置类1.2 得出结论&#xff0c;需要增加配置1.3 调试 二、OkHttpFeignLoadBalancerConfiguration 的启用2.1 分析配置类2.2 得出结论2.3 测试 附录附1&#xff1a;本系列文章链接附2&#xff1a;OkHttpClient 增…

1|1111

1、指定在每天凌晨4&#xff1a;00将该时间点之前的系统日志信息&#xff08;/var/log/messages &#xff09;备份到目录下/backup&#xff0c;备份后日志文件名显示格式logfileYY-MM-DD-HH-MM 2、配置ssh免密登陆&#xff1a;客户端主机通过redhat用户基于秘钥验证方式进行远…

数据结构——单链表(Singly Linked List)

1.链表介绍 链表是一种物理储存上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点&#xff08;链表中每一个元素称为结点&#xff09;组成&#xff0c;结点可以在运行时动态生成。 对于上图&#xff0c;每一个结点都是一个结…

NFT Insider115:The Sandbox开设元宇宙Diorama快闪店,​YGG Web3 游戏峰会已开幕

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members、BeepCrypto联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周报将从NFT市场数据&#xff0c;艺术新闻类&#xff0c;游戏新闻类&#xff0c;虚拟世界类&#…

项目中如何配置数据可视化展现

在现今数据驱动的时代&#xff0c;可视化已逐渐成为数据分析的主要途径&#xff0c;可视化大屏的广泛使用便应运而生。很多公司及政务机构&#xff0c;常利用大屏的手段展现其实力或演示业务&#xff0c;可视化的效果能让观者更快速的理解结果并直观的看到数据展现。因此&#…

仿 美图 / 饿了么,店铺详情页功能

前言 UI有所不同&#xff0c;但功能差不多&#xff0c;商品添加购物车功能 正在写&#xff0c;写完会提交仓库。 效果图一&#xff1a;左右RecyclerView 联动 效果图二&#xff1a;通过点击 向上偏移至最大值 效果图三&#xff1a;通过点击 或 拖动 展开收缩公告 效果图四&…

Modown主题v8.12 安装教程和主题下载

亲测」Modown主题v8.12学习版 上传好主题选择该主题就好了设置 设置好的首页 内容页&#xff1a; WordPress主题Modown和WordPress插件Erphpdown想必正在使用WordPress程序建站的站长都非常熟悉&#xff0c;因为这两款应用在WordPress站长圈子里还是比较知名的&#xff0c;所以…

LangChain 9 模型Model I/O 聊天提示词ChatPromptTemplate, 少量样本提示词FewShotPrompt

LangChain系列文章 LangChain 实现给动物取名字&#xff0c;LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄LangChain 4用向量数据库Faiss存储&#xff0c;读取YouTube的视频文本搜索I…