二叉树——堆

二叉树顺序存储结构

  理解堆之前先理解一下二叉树的顺序存储结构。普通的二叉树并不适合顺序存储,因为可能会造成大量的空间浪费。只有完全二叉树适合顺序结构存储。显示中我们通常把堆使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统中虚拟进程地中空间中的堆是两回事,这个堆是一个数据结构,而虚拟进程地址空间中的堆是操作系统中管理内存的一块区域分段。
在这里插入图片描述
在这里插入图片描述

堆的概念

  如果有一个关键码集合K={k0,k1,……kn-1},把所有的元素按完全二叉树的吮吸存储方式存储在一个一维数组,并满足:ki<=k2i+1并且ki<=k2i+2,就程这个二叉树为小堆(大堆)。根节点是最大值的堆称为大堆,根节点为最小值称为小堆。

堆的性质

  1. 队中每个结点的值总是不大于或者不小于其父节点
  2. 堆总是一个完全二叉树
  3. 堆中第N个节点的左孩子为第N2+1个节点,右孩子为第N2+2个节点
    在这里插入图片描述

堆的实现

创建堆

在这里插入图片描述
  这个数组从逻辑上可以看作是一个完全二叉树,但他还不是一个堆,需要我们运用向下调整算法将他构成一个堆。对于二叉树来说,如果根节点的左右子树都满足堆,那么这个二叉树就满足堆,所以我们从倒数第二个尾叶子节点开始调整,一直调整到到整个二叉树的根节点为止。

向下调整算法(小堆)

  向下调整算法就是从当前节点开始,依次向下调整,直到不满足条件为止:

  1. 找出当前节点的两个孩子中的最小的孩子(先找左孩子,根据完全二叉树的性质可以直到左孩子存在,右孩子不一定存在)
  2. 如果当前节点比最小的孩子大,就需要与这个孩子交换位置,然后继续向下调整
  3. 如果当前节点比最小的孩子小,就可以结束调整,说明以当前节点为根的二叉树是小堆。
    在这里插入图片描述
    向下调整代码
void AdjustDown(HPData* array, int size, int root, PCOM compare)
{int child = root * 2 + 1;while (child < size){//找左右孩子中最小的孩子if (child + 1 < size && compare(array[child],array[child - 1]))child += 1;if (compare(array[child], array[root])){swap(array[root], array[child]);root = child;child = root * 2 + 1;}elsereturn;}
}
堆插入

  堆创建好了,接下来就是向堆中插元素,只需要将元素放在堆底,然后向上调整
  向上调整就是用当前节点与父节点比较,如果比父结点小,就要交换,然后继续向上调整,如果比父结点大,就结束调整
在这里插入图片描述

堆删除

  堆删除时将对顶元素删除,先将堆顶元素和最后一个元素交换位置,将最后一个元素删除即可,最后从堆顶向下调整。在这里插入图片描述

堆代码的实现


int less(HPData left, HPData right)
{return left < right;
}
int greater(HPData left, HPData right)
{return left > right;
}
//定义函数指针来改变大堆和小堆
typedef int(*PCOM)(HPData left, HPData right);
int less(HPData left, HPData right);
int greater(HPData left, HPData right);//堆结构体
typedef struct Heap
{HPData* _array;int _size;int _capacity;PCOM _compare;
}Heap;//向下调整
void AdjustDown(HPData* array, int size, int root, PCOM compare)
{int child = root * 2 + 1;while (child < size){//找左右孩子中最小的孩子if (child + 1 < size && compare(array[child],array[child - 1]))child += 1;if (compare(array[child], array[root])){swap(array[root], array[child]);root = child;child = root * 2 + 1;}elsereturn;}
}//向上调整
void AdjustUp(HPData* array, int size, int child, PCOM compare)
{int root = (child - 1) >> 1;while (child){if (compare(array[child], array[root])){swap(array[root], array[child]);child = root;root = (child - 1) >> 1;}elsereturn;}
}//堆扩容
void CheckCapacity(Heap* hp)
{assert(hp);int newcapacity = hp->_size * 2;HPData* array = (HPData*)malloc(sizeof(HPData) * newcapacity);if (array == NULL){assert(0);return;}for (int i = 0; i < hp->_size; ++i)array[i] = hp->_array[i];hp->_capacity = newcapacity;free(hp->_array);hp->_array = array;
}//初始化堆
void InitHeap(Heap* hp, HPData* array, int size, PCOM compare)
{assert(hp);hp->_array = (HPData*)malloc(sizeof(HPData)*size);if (NULL == hp->_array){assert(0);return;}hp->_capacity = size;hp->_size = size;hp->_compare = compare;for (int i = 0; i < size; ++i)hp->_array[i] = array[i];int root = ((size - 2) >> 1);for ( ;root >= 0; --root)AdjustDown(hp->_array, size, root, compare);
}//堆插入
void InsertHeap(Heap* hp, HPData data, PCOM compare)
{if (hp->_size == hp->_capacity)CheckCapacity(hp);hp->_array[hp->_size] = data;AdjustUp(hp->_array, hp->_size, hp->_size - 1, compare);}//堆中元素个数
int HeapSize(Heap* hp)
{assert(hp);return hp->_size;
}//堆顶元素
HPData HeapTop(Heap* hp)
{assert(hp);return hp->_array[0];
}//判断是否是空堆
bool HeapEmpty(Heap* hp)
{assert(hp);return hp->_size == 0;
}//删除堆元素
void EraseHeap(Heap* hp)
{if (HeapEmpty(hp))return;swap(hp->_array[0], hp->_array[hp->_size - 1]);hp->_size -= 1;AdjustDown(hp->_array, hp->_size, 0, hp->_compare);
}//销毁堆
void DostroyHeap(Heap* hp)
{assert(hp);if (hp->_array){free(hp->_array);hp->_capacity = 0;hp->_size = 0;}
}

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

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

相关文章

open AI 在DOTA 5v5 比赛中战胜职业选手

来源&#xff1a;AI科技大本营摘要&#xff1a;去年&#xff0c;OpenAI 在 DOTA 的 1v1 比赛中战胜了职业玩家 Dendi&#xff0c;而在距离进阶版 OpenAI Five 系统战胜人类业余玩家不过一个月的时间&#xff0c;今天凌晨&#xff0c;它又以 2:1 的战绩再次完成对人类高级玩家的…

如何体现机器智能和群体智能的关系,2018新版互联网大脑模型绘制

作者&#xff1a;刘锋 计算机博士 互联网进化论作者2018年新的这一版&#xff0c;也是互联网大脑模型图的第五个版本&#xff0c;距离第一版的发布已经有10年时间&#xff08;2008年&#xff09;&#xff0c;距离上一版第四版也有1年时间&#xff0c;在这一版中主要解决了如何…

全球互联正在创造一个知识极大丰富和隐私终结的时代

来源&#xff1a;资本实验室摘要&#xff1a;据预测&#xff0c;到2020年&#xff0c;全球物联网连接设备将超过500亿个&#xff0c;会产生600泽字节的信息。这么庞大的数据量&#xff0c;将如何影响并改变我们的生活和工作&#xff1f;聚焦前沿科技创新与传统产业升级据预测&a…

泡沫破裂之后,强化学习路在何方?

作者&#xff5c;侯宇清、陈玉荣来源&#xff5c;智能单元编辑&#xff5c;Debra一、深度强化学习的泡沫2015 年&#xff0c;DeepMind 的 Volodymyr Mnih 等研究员在《自然》杂志上发表论文 Human-level control through deep reinforcement learning[1]&#xff0c;该论文提出…

一篇文章搞懂数据仓库:维度表(设计原则、设计方法)

目录 1、什么是维度表&#xff1f; 2、维度表设计原则 &#xff08;1&#xff09;维度属性尽量丰富&#xff0c;为数据使用打下基础 &#xff08;2&#xff09;给出详实的、富有意义的文字描述 &#xff08;3&#xff09;区分数值型属性和事实 &#xff08;4&#xff09;…

Github项目:AI消除马赛克实战

目录 1、原理 2、准备工作 3、消除马赛克 4、效果对比 1、原理 该算法利用线性盒滤波器分别处理每个块的事实。对于每个块&#xff0c;它将搜索图像中的所有块像素化以检查直接匹配。 对于大多数像素化图像&#xff0c;Depix能够找到单个匹配结果。它假设这些是正确的。然…

C++继承一览

继承的概念及定义 继承机制是面向对象程序设计是代码可以复用的重要手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生的类称为派生类。继承呈现了面向对象程序设计的层次结构&#xff0c;体现了由简单到复杂的认知过程。…

人工智能能否复制人脑引争论 美媒:目前AI仍存在局限性

来源&#xff1a;网易智能摘要&#xff1a;人们应用人工智能技术&#xff08;AI&#xff09;的所有领域&#xff0c;包括无人驾驶汽车、机器人医生、超过10亿中国公民的社会信用评分系统等&#xff0c;当前都取决于一场关于如何让AI做其不能做的事的辩论。8月6日报道称&#xf…

Tushare免费获取股票数据:实时数据,历史数据,行情数据

一 操作手册 引导用户顺利开始使用Tushare Pro数据&#xff0c;以下步骤将带您开始Tushare数据之旅&#xff1a; 用户注册登录后可调用数据&#xff1a;https://tushare.pro/register?reg399205 二 如何获取TOKEN凭证 1、登录成功后&#xff0c;点击右上角->个人主页 2、…

排序(冒泡、选择、插入、希尔、快排、堆排、归并)

冒泡排序 冒泡排序时通过无序区中相邻记录的关键字间的比较和位置的交换&#xff0c;使关键字最小的元素如气泡似的逐步上浮直水面。有序区逐渐扩大&#xff0c;无序区逐渐缩小。   冒泡排序算法的原理如下&#xff1a; 比较相邻的元素。如果第一个比第二个大&#xff0c;就…

人民日报:人工智能,务实发展是正道

来源&#xff1a;人民日报摘要&#xff1a;近日&#xff0c;由中国人工智能学会主办的中国人工智能大会在深圳召开&#xff0c;利用这个人工智能领域产、学、研紧密结合的高端前沿交流平台&#xff0c;围绕关键核心技术发展等当前热点话题&#xff0c;学者和业界人士进行了充分…

自动驾驶芯片:GPU 的现在和 ASIC 的未来

来源&#xff1a;乐晴智库精选▌车载芯片的发展趋势(CPU-GPU-FPGA-ASIC)过去汽车电子芯片以与传感器一一对应的电子控制单元(ECU)为主&#xff0c;主要分布与发动机等核心部件上。随着汽车智能化的发展&#xff0c;汽车传感器越来越多&#xff0c;传统的分布式架构逐渐落后&…

电动汽车:新一轮三年十倍,“补贴”结束“高端”开启

来源&#xff1a;乐晴智库精选摘要&#xff1a;从最早的十城千辆新能源车示范推广&#xff0c;到2014年正式启动的二级市场新能源车大行情&#xff0c;再到当下新能源乘用车型的快速升级迭代&#xff0c;新能源汽车产业发展和投资已历经8余年。▌新能源汽车投资&#xff0c;推倒…

使用easyUI给datagrid添加pagination

author YHC 这个示例展示我们如何从服务器端加载数据和如何添加pagination 到datagrid. 查看 Demo 创建 DataGrid 从服务器端加载数据, 你应该设置url属性, 在你的服务器端你应该返回JSON格式数据.请看datagrid文档得到更多关于它的数据格式信息. <table id"tt" c…

一篇文章搞懂数据仓库:四种常见数据模型(维度模型、范式模型等)

目录 写在前面 一、为什么要进行数据仓库建模&#xff1f; 二、四种常见模型 2.1 维度模型 2.1.1 星型模型 2.1.2 雪花模型 2.1.3 星座模型 2.2 范式模型 2.3 Data Vault模型 2.4 Anchor模型 三 数据模型的评价标准 小编有话 写在前面 大数据时代&#xff0c;维度…

学习C语言可以从以下几个方面入手

学习C语言可以从以下几个方面入手&#xff1a; 了解基础知识&#xff1a;首先&#xff0c;你需要了解C语言的基本语法和规则&#xff0c;包括变量、数据类型、运算符、控制结构等。可以通过阅读相关的教材或在线教程来学习这些基础知识。动手实践&#xff1a;理论知识的学习是…

王飞跃谈GE艰难的数字化转型启示:从工业智联网到工业5.0

来源&#xff1a;德先生外患&#xff1a;2018年6月26日&#xff0c;通用电气&#xff08;下文称GE&#xff09;被剔除出道琼斯工业平均指数&#xff0c;而GE自1907年即是道指成分股&#xff0c;至今坚守了111年。2017年以来&#xff0c;通用电气股价从30美元左右下跌到现在的13…

一篇文章搞懂数据仓库:常用ETL工具、方法

目录 一、什么是ETL&#xff1f; 二、ETL & ELT 三、常用的ETL工具 3.1 sqoop 3.2 DataX 3.3 Kettle 3.4 canal 3.5 StreamSets 四、ETL加载策略 4.1 增量 4.2 全量 4.3 流式 小编有话 一、什么是ETL&#xff1f; ETL&#xff0c;是英文Extract-Transform-Lo…

经典排序之 堆排序

开了个公众号「aCloudDeveloper」&#xff0c;专注技术干货分享&#xff0c;期待与你相遇。 Author: bakari Date: 2012.7.30 排序算法有很多种&#xff0c;每一种在不同的情况下都占有一席之地。关于排序算法我分“经典排序之”系列分别述之。本篇为堆排序。 堆排序是运用二叉…

操作系统之进程概念

进程概念 进程是什么&#xff1a; 表面上来说进程是程序的一个执行实例&#xff0c;或者是一个正在执行的程序等&#xff0c;从操作系统的角度来说&#xff0c;程序运行需要将代码数据加载到内存中&#xff0c;由于在操作系统中运行了很多的程序&#xff0c;操作系统就必须去管…