外贸做网站/爱链网买链接

外贸做网站,爱链网买链接,有哪些做汽车变速箱的门户网站,电商网站平台有哪些功能模块💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习! 👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对数据结构感…

💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习!
👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对数据结构感兴趣的朋友

文章目录

前言

堆是一种基于完全二叉树的数据结构,通常分为最大堆(父节点值≥子节点)和最小堆(父节点值≤子节点)。由于完全二叉树的特性,堆可以用数组高效存储,通过索引关系快速定位父子节点。


1. 堆的概念与结构

如果有⼀个关键码的集合,把它的所有元素按完全⼆叉树的顺序存储⽅式存储,在⼀个⼀维数组中,并满⾜: K = { k 0 , k 1 , k 2 , . . . , k n − 1 } K=\{ k_0,k_1,k_2,...,k_{n-1} \} K={k0,k1,k2,...,kn1}i = 0、1、2...,则称为⼩堆(或⼤堆)。将根结点最⼤的堆叫做最⼤堆或⼤根堆,根结点最⼩的堆叫做最⼩堆或⼩根堆。

在这里插入图片描述


1.2 堆的重要性质

对于具有n个结点的完全二叉树,如果按照从上至下、从左至右的数组顺序对所有结点从0开始编号,对于序号为i的结点有:

  1. i > 0i位置结点的双亲序号为:(i - 1)/2; 当i0时,i为根结点。
  2. 2i + 1 < n,左孩子序号:2i + 1;如果2i + 1 >=n,则无左孩子
  3. 2i + 2 < n,左孩子序号:2i + 2;如果2i + 2 >=n,则无右孩子

2. 堆的实现

原码自取gitee

现在我们知道,完全二叉树的顺序结构就是堆,顾名思义,堆就是用顺序表(数组)实现的。
在这里插入图片描述
Heap.h

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#include<time.h>typedef int HPDataType;
typedef struct Heap
{HPDataType* a;//堆int size;//堆的大小int capacity;//堆的容量
}HP;
//堆的初始化
void HeapInit(HP* php);
// 堆的销毁
void HeapDestory(HP* php);
// 堆的插入
void HeapPush(HP* php, HPDataType x);
// 堆的删除
void HeapPop(HP* php);
// 取堆顶的数据
HPDataType HeapTop(HP* php);
// 堆的数据个数
int HeapSize(HP* php);
// 堆的判空
int HeapEmpty(HP* php);
//向下调整
void AdjustDown(HPDataType* a, int n, int parent);
//向上调整
void AdjustUp(HPDataType* a, int child);
//交换
void swap(HPDataType* p1, HPDataType* p2);

声明:本文以实现小堆为例,如需实现大堆,修改小堆调整算法的条件即可,这里不过多赘述。


2.1 堆的插入+向上调整算法

2.1.1 向上调整算法

该算法辅助实现堆的插入

将新数据插入到数组的尾上,再进行向上调整算法,直到满足堆。

在这里插入图片描述
仔细观察这个图解,不难发现:从某个结点出发,与其父亲比较,如果小于他的父亲,就交换位置;如果大于或等于就不动,调整结束。

void AdjustUp(HPDataType* a,int child)
{int parent = (child - 1) / 2;while (child > 0) {if (a[child] > a[parent]) {swap(&a[child],&a[parent]);child = parent;parent = (child - 1) / 2;}else {break;}}
}

2.1.2 堆的插入
  • 先将元素插⼊到堆的末尾,即最后⼀个孩⼦之后
  • 插⼊之后如果堆的性质遭到破坏,将新插⼊结点顺着其双双亲往上调整到合适位置即可

在这里插入图片描述

void HeapPush(HP* php, HPDataType x)
{assert(php);//若空间不足,则扩容if (php->size == php->capacity) {HPDataType* ptr = realloc(php->a, sizeof(HPDataType) * php->capacity * 2);if (ptr == NULL) {perror("realloc fail");exit(-1);}php->a = ptr;php->capacity *= 2;}php->a[php->size] = x;AdjustUp(php->a, php->size);php->size++;
}

2.2 堆的删除+向下调整算法

2.2.1 向下调整算法

该算法辅助实现堆的删除

现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提左右子树必须是一个堆,才能调整。

int array[] = {27,15,19,18,28,34,65,49,25,37};

向下调整过程图
仔细观察这个图解,不难发现:从根结点出发,与其较小的孩子比较,如果小于这个孩子,就交换位置;如果大于或等于就不动,调整结束。

代码核心:

  1. 父亲与孩子的下标关系:child=2*parent + 1
  2. 孩子的下标小于n,避免数组越界访问
void AdjustDown(HPDataType* a,int n,int parent)
{int child = 2 * parent + 1;while (child < n) {// 假设法,选出左右孩⼦中⼩的那个孩⼦if (a[child] < a[child + 1] && child + 1 < n){child++;}if (a[parent] < a[child]) {swap(&a[parent], &a[child]);parent = child;child = 2 * parent + 1;}else break;}
}

2.2.2 堆的删除

删除时需注意判断堆是否为非空,若对空堆进行删除,必然出错。

  • 将堆顶元素与堆中最后⼀个元素进⾏交换
  • 删除堆中最后⼀个元素
  • 将堆顶元素向下调整到满⾜堆特性为⽌
    在这里插入图片描述
void HeapPop(HP* php)
{assert(php);assert(!HeapEmpty(php));swap(php->a,&php->a[php->size-1]);php->size--;AdjustDown(php->a,php->size, 0);
}

其余的初始化、销毁、判空等等,非常简单,都是老套路了,这里留给读者自己发挥。
在我过去的一些文章都有类似的详解(顺序表、链表、栈、队列)。大家可以照猫画虎。

传送门呈上~
【初探数据结构】线性表———顺序表的详解和实现
【初探数据结构】线性表————链表(一)(单链表的实现)
【初探数据结构】线性表——链表(二)带头双向循环链表(详解与实现)
【初探数据结构】线性表——栈与队列(代码实现与详解)


3. 复杂度分析(向上调整与向下调整)

因为堆是完全二叉树,而满二叉树也是完全二叉树,为了简化证明,此出以满二叉树为研究对象。(时间复杂度本来看的就是近似值,多几个节点不影响最终结果)


3.1 向下调整时间复杂度( O ( N ) O(N) ON

最坏的情况是什么呢?
就是树的每个结点全部都要进行一次调整堆底。
设树的高度为h
我们需要计算的是向下移动的总次数T(n)
在这里插入图片描述
分析:
第1层, 2 0 2^0 20个结点,需要向下移动h-1
第2层, 2 1 2^1 21个结点,需要向下移动h-2
第3层, 2 2 2^2 22个结点,需要向下移动h-3
第4层, 2 3 2^3 23个结点,需要向下移动h-4

第h-1层, 2 h − 2 2^{h-2} 2h2 个结点,需要向下移动1

则需要移动结点总的移动步数为:每层结点个数乘向下调整次数

T ( h ) = 2 0 ∗ ( h − 1 ) + 2 1 ∗ ( h − 2 ) + 2 2 ∗ ( h − 3 ) + 2 3 ∗ ( h − 4 ) + … … + 2 h − 3 ∗ 2 + 2 h − 2 ∗ 1 T(h) = 2^0*(h-1)+ 2^1*(h-2)+2^2*(h-3)+2^3*(h-4)+……+2^{h-3}*2+2^{h-2}*1 T(h)=20(h1)+21(h2)+22(h3)+23(h4)+……+2h32+2h21

利用数列的错位相减(计算步骤如下图)
在这里插入图片描述
得出:
T ( h ) = 2 h − 1 − h T(h) = 2^h −1 − h T(h)=2h1h
根据⼆叉树的性质:
n = 2 h − 1 和 h = l o g 2 ( n + 1 ) n = 2^h-1和h=log_2(n+1) n=2h1h=log2(n+1)

得出:
T ( n ) = n − l o g 2 ( n + 1 ) ≈ n T(n)=n-log_2(n+1)≈n T(n)=nlog2(n+1)n

向下调整算法建堆时间复杂度为:O(n)


3.2 向上调整时间复杂度( n ∗ l o g n n*logn nlogn)

与向下调整类似,计算所有结点向上移动至堆顶的移动总次数即可
设树的高度为h
我们需要计算的是向上移动的总次数T(n)

分析:
第1层, 2 0 2^0 20个结点,需要向下移动0
第2层, 2 1 2^1 21个结点,需要向下移动1
第3层, 2 2 2^2 22个结点,需要向下移动2
第4层, 2 3 2^3 23个结点,需要向下移动3

第h层, 2 h − 2 2^{h-2} 2h2 个结点,需要向下移动h-1

则需要移动结点总的移动步数为:每层结点个数乘向上调整次数(第⼀层调整次数为0)

T ( h ) = 2 1 ∗ 1 + 2 2 ∗ 2 + 2 3 ∗ 3 + … … + 2 h − 2 ∗ ( h − 2 ) + 2 h − 1 ∗ ( h − 1 ) T(h) = 2^1*1+2^2*2+2^3*3+……+2^{h-2}*(h-2)+2^{h-1}*(h-1) T(h)=211+222+233+……+2h2h2+2h1(h1)

也是利用数列的错位相减得:
T ( h ) = − ( 2 h − 1 ) + 2 h ∗ ( h − 1 ) + 2 0 T(h) = -(2^h-1)+2^h * (h-1)+2^0 T(h)=(2h1)+2hh1+20
根据⼆叉树的性质:
n = 2 h − 1 和 h = l o g 2 ( n + 1 ) n = 2^h-1和h=log_2(n+1) n=2h1h=log2(n+1)

得出:
T ( n ) = ( n + 1 ) ( l o g 2 ( n + 1 ) − 2 ) + 2 ≈ n ∗ l o g 2 n T(n)=(n + 1)(log_2(n +1) − 2) + 2≈n*log_2n T(n)=(n+1)(log2(n+1)2)+2nlog2n

向上调整算法建堆时间复杂度为: n ∗ l o g n n*logn nlogn


3.3 结论

由此可见,向下调整的效率是优于向上调整的,所以我们以后需要建堆时,应该优先考虑向下调整建堆。再后面的堆排序中我们可以深刻体会到。


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

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

相关文章

流量分析2

一&#xff0c;webshell流量 [GKCTF 2021]签到 先看协议分级&#xff0c;大部分是tcp&#xff0c;里面有http的基于的行文本数据占了很大的比重&#xff0c;看看里面有什么 过滤http的流量 点击一条流量&#xff0c;里面的内容进去后面有基于行的文本数据&#xff0c; 先解he…

头歌实践教学平台--【数据库概论】--SQL

一、表结构与完整性约束的修改(ALTER) 1.修改表名 USE TestDb1; alter table your_table rename TO my_table; 2.添加与删除字段 #语句1&#xff1a;删除表orderDetail中的列orderDate alter table orderDetail drop orderDate; #语句2&#xff1a;添加列unitPrice alter t…

vue h5实现车牌号输入框

哈喽&#xff0c;大家好&#xff0c;最近鹏仔开发的项目是学校校内车辆超速方面的统计检测方面的系统&#xff0c;在开发过程中发现有个小功能&#xff0c;就是用户移动端添加车牌号&#xff0c;刚开始想着就一个输入框&#xff0c;提交时正则效验一下格式就行&#xff0c;最后…

硬件基础(5):(3)二极管的应用

文章目录 [toc]1. **整流电路****功能**&#xff1a;**工作原理**&#xff1a;**应用实例**&#xff1a;电路组成&#xff1a;整流过程&#xff1a;电路的应用&#xff1a; 2. **稳压电路****功能**&#xff1a;**工作原理**&#xff1a;**应用实例**&#xff1a;电路组成及功能…

ElementUI el-menu导航开启vue-router模式

有没有小伙伴遇到这么一种情况&#xff1a;ElementUI el-menu导航中&#xff0c;开启vue-router 的模式后&#xff0c;点击触发事件而不进行路由跳转&#xff1f; 别慌&#xff01;下面直接说解决方案&#xff1a; 借助路由守卫进行判断 给el-menu绑定切换事件&#xff0c;给…

Vue 2 探秘:visible 和 append-to-body 是谁的小秘密?

&#x1f680; Vue 2 探秘&#xff1a;visible 和 append-to-body 是谁的小秘密&#xff1f;&#x1f914; 父组件&#xff1a;identify-list.vue子组件&#xff1a;fake-clue-list.vue 嘿&#xff0c;各位前端探险家&#xff01;&#x1f44b; 今天我们要在 Vue 2 的代码丛林…

C++学习之路:从头搞懂配置VScode开发环境的逻辑与步骤

目录 编辑器与IDE基于vscode的C开发环境配置1. 下载vscode、浅尝编译。番外篇 2. 安装插件&#xff0c;赋能编程。3. 各种json文件的作用。c_cpp_properties.jsontask.jsonlaunch.json 总结&&彩蛋 编辑器与IDE 上一篇博客已经介绍过了C程序的一个编译流程&#xff0c;从…

PPT 转高精度图片 API 接口

PPT 转高精度图片 API 接口 文件处理 / 图片处理&#xff0c;将 PPT 文件转换为图片序列。 1. 产品功能 支持将 PPT 文件转换为高质量图片序列&#xff1b;支持 .ppt 和 .pptx 格式&#xff1b;保持原始 PPT 的布局和样式&#xff1b;转换后的图片支持永久访问&#xff1b;全…

VSCode 抽风之 两个conda环境同时在被激活

出现了神奇的(toolsZCH)(base) 提示符&#xff0c;如下图所示&#xff1a; 原因大概是&#xff1a;conda 环境的双重激活&#xff1a;可能是 conda 环境没有被正确清理或初始化&#xff0c;导致 base 和 toolsZCH 同时被激活。 解决办法就是 &#xff1a;conda deactivate 两次…

git | 回退版本 并保存当前修改到stash,在进行整合。[git checkout | git stash 等方法 ]

目录 一些常见命令&#xff1a; git 回退版本 一、临时回退&#xff08;不会修改历史&#xff0c;可随时回到当前版本&#xff09; 方法1&#xff1a;git checkout HEAD~1 问题&#xff1a;处于 detached HEAD 状态下提交的&#xff0c;无法直接 git push ✅ 选项 1&…

如何使用 Postman 进行接口测试?

使用 Postman 这一工具&#xff0c;可以轻松地进行接口测试。以下是一份简单的使用教程&#xff0c;帮助你快速上手。 Postman 接口测试教程&#xff1a;详细步骤及操作技巧

写作软件新体验:让文字创作更高效

一、开篇引入:写作难题的破解之道 在当今信息爆炸的时代,写作成为了我们生活和工作中不可或缺的一部分。然而,面对繁琐的写作任务,我们时常感到力不从心,甚至陷入创作的瓶颈。那么,有没有一款软件能够帮助我们破解这一难题,让文字创作变得更加高效和轻松呢?答案是肯定…

大模型思维链COT:Chain-of-Thought Prompting Elicits Reasoningin Large Language Models

一、TL&#xff1b;DR 探索了COT&#xff08;chain-of-thought prompting&#xff09;通过一系列的中间推理步骤来显著的提升了LLM的复杂推理能力在三个大型语言模型上的实验表明&#xff0c;思维链提示能够提升模型在一系列算术、常识和符号推理任务上的表现解释了一下为什么…

决策树算法详解:从西瓜分类到实战应用

目录 0. 引言 1. 决策树是什么&#xff1f; 1.1 生活中的决策树 1.2 专业版决策树 2. 如何构建决策树&#xff1f; 2.1 关键问题&#xff1a;选哪个特征先判断&#xff1f; 2.1.1 信息熵&#xff08;数据混乱度&#xff09; 2.1.2 信息增益&#xff08;划分后的整洁度提…

超融合服务器是什么

超融合服务器的定义与背景 超融合服务器&#xff08;Hyperconverged Infrastructure, HCI&#xff09;是一种通过软件定义技术&#xff0c;将计算、存储、网络和虚拟化功能整合到单一硬件平台中的IT基础设施解决方案。其核心目标是通过资源的高度集成和统一管理&#xff0c;简…

【网络层协议】NAT技术内网穿透

IP地址数量限制 我们知道&#xff0c;IP地址&#xff08;IPv4&#xff09;是一个4字节32位的整数&#xff0c;那么一共只有2^32也就是接近43亿个IP地址&#xff0c;而TCP/IP协议栈规定&#xff0c;每台主机只能有一个IP地址&#xff0c;这就意味着&#xff0c;一共只有不到43亿…

时隔多年,终于给它换了皮肤,并正式起了名字

时隔多年&#xff0c;终于更新了直播推流软件UI&#xff0c;并正式命名为FlashEncoder。软件仍使用MFC框架&#xff0c;重绘了所有用到的控件&#xff0c;可以有效保证软件性能&#xff0c;也便于后续进一步优化。 下载地址&#xff1a;https://download.csdn.net/download/Xi…

如何避免测试环境不稳定导致的误报

避免测试环境不稳定导致误报的核心方法包括搭建独立稳定的测试环境、使用环境监控工具、建立环境变更管理机制、定期维护更新测试环境以及提升团队的环境管理意识。 其中&#xff0c;搭建独立稳定的测试环境尤为关键。独立的测试环境能有效隔离其他环境的干扰&#xff0c;保证测…

Axure RP9教程 :轮播图(动态面板) | 头部锁定

文章目录 引言I 轮播图操作步骤在画布中添加一个动态面板设置面板状态II 头部锁定将头部区域选中,右键组合或用Ctrl+G快捷键;将组合的头部区域,右键创建动态面板;引言 动态面板的功能十分强大,比如:拥有独立的内部坐标系,有多个状态; Banner的案例中会用到动态面板多个…

Docker入门篇4:查看容器资源、查看容器详细信息、查看容器日志、查看容器内运行的进程

大家好我是木木&#xff0c;在当今快速发展的云计算与云原生时代&#xff0c;容器化技术蓬勃兴起&#xff0c;Docker 作为实现容器化的主流工具之一&#xff0c;为开发者和运维人员带来了极大的便捷 。下面我们一起开始入门第四篇&#xff1a;查看容器资源、查看容器详细信息、…