数据结构-堆详解

图片:

二叉堆的父节点为这个子树的最值。

如何维护它。
我们发现它是一棵二叉树,那就自然满足若父节点为 x x x 则左儿子节点为 x × 2 x\times2 x×2 右儿子为 x × 2 + 1 x\times 2 + 1 x×2+1 这是显然的,但如果写成指针或结构体就太麻烦了,所以考虑用数组来维护它。

用一个数组 T T T 来存储这颗二叉树,根节点为 T 1 T_1 T1 根据二叉树的性质对于每个子节点 x x x 则有:

  1. x > 1 x>1 x>1 则fa[x]=i/2;
  2. 2 × x > n 2\times x>n 2×x>n x x x 没有儿子,如果 2 × x + 1 > n 2\times x+1>n 2×x+1>n x x x 没有右儿子。
  3. 如果节点 x x x 有孩子,则 x x x 的左儿子为 x × 2 x\times 2 x×2 右儿子为 x × 2 + 1 x\times 2 + 1 x×2+1

复杂度分析:

这样做由于二叉树只有 log ⁡ 2 n \log_2n log2n 层,自然单次复杂度为 O ( log ⁡ 2 n ) O(\log_2n) O(log2n)可以解决 n ≤ 1 0 6 n\leq 10^6 n106 及以下的问题。

那么该如何让这个二叉树平衡?通常使用上浮法与下沉法。
例子:
假设你已经有一个堆了,就是上面那个

这个时候你如果想要给它加入一个节点怎么办,比如说0?

先插到堆底(严格意义上来说其实0是在5的左儿子的,图没画好放不下去,不过也不影响)

然后你会发现它比它的父亲小啊,那怎么办?不符合小根堆的性质了啊,那就交换一下他们的位置

交换之后还是发现不符合小根堆的性质,那么再换

还是不行,再换

好了,这下就符合小根堆的性质了。

事实上堆的插入就是把新的元素放到堆底,然后检查它是否符合堆的性质,如果符合就丢在那里了,如果不符合,那就和它的父亲交换一下,一直交换交换交换,直到符合堆的性质,那么就插入完成了。
删除同理这里不在复述了。

代码:

插入:

void push(int x){h[++len] =x;int i=len;while(i>1 && h[i]<h[len/2]){swap(h[i],h[i/2]);i/=2;}
}

删除:

void pop(){h[1] = h[len--];int i=1;while((i<<1)<=len){int son=(i<<1);if(son<len&&h[son+1]<h[son]){son++;}if(h[son]<h[i]){swap(h[son],h[i]);i=son;}else break;}
}

STL堆:

算法竞赛中虽然STL没有手写快但是否好像实用代码:

定义一个大根堆即堆内为递减的序列

priority_queue<int> Q;

小根堆:

priority_queue<int,vector<int>,greater<int>> Q2;

使用:

插入一个数:

void insert(int x){q.push(x);
}

删除堆头:

void erase(){q.pop();
}

访问堆头

int front(){return q.top();
}

建议使用STL的堆

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

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

相关文章

Redis的特性与安装

回顾 Redis是一个在内存中存储数据的中间件&#xff0c;可以用来当数据库用&#xff0c;也可以作为缓存用(这里的缓存往往是对数据库缓存)。 中间件&#xff1a;和业务无关的服务&#xff0c;功能更加通用&#xff0c;如&#xff1a;数据库&#xff0c;缓存&#xff0c;消息队…

【笔试强训】Day1 --- 数字统计 + 两个数组的交集 + 点击消除

文章目录 1. 数字统计2. 两个数组的交集3. 点击消除 1. 数字统计 【链接】&#xff1a;数字统计 解题思路&#xff1a;模拟&#xff0c;利用数学知识&#xff0c;计算每个数字中2出现的个数。&#xff08;这里也可以将数字转换成字符串来统计字符’2’出现的个数&#xff09…

C# 语言类型(五)—其他

总目录 C# 语法总目录 参考链接&#xff1a; C#语法系列:C# 语言类型(一)—预定义类型值之数值类型 C#语法系列:C# 语言类型(二)—预定义类型之字符串及字符类型简述 C#语法系列:C# 语言类型(三)—数组/枚举类型/结构体 C#语法系列:C# 语言类型(四)—传递参数及其修饰符 C#语法…

如何使用Flask搭建web程序框架并实现无公网IP远程访问本地程序

文章目录 前言1. 安装部署Flask并制作SayHello问答界面2. 安装Cpolar内网穿透3. 配置Flask的问答界面公网访问地址4. 公网远程访问Flask的问答界面 前言 Flask是一个Python编写的Web微框架&#xff0c;让我们可以使用Python语言快速实现一个网站或Web服务&#xff0c;本期教程…

模拟器无法ADB链接的所有情况及解决方案

前言&#xff1a; adb&#xff08;Android Debug Bridge&#xff09;安卓调试桥&#xff0c;简单可以理解为外部连接安卓内部的一个接口&#xff0c;走的是tcp协议。 但是在模拟器上面经常会遇到连不上adb&#xff0c;在此收集一下各种情况&#xff0c;想起来或者遇到了就更新…

bonding原理分析和问题排查

bonding原理 发送端&#xff1a; 使用网卡bond3模式&#xff08;广播模式BOND_MODE_BROADCAST&#xff09;将报文从两个网卡同时发出&#xff0c;无需修改报文。 接收端&#xff1a; 根据发送节点时间的链路通断状态&#xff0c;接收端设置一条线路为活动线&#xff0c;另一条…

免费泛域名SSL如何申请,和通配符有什么区别

-----让我们明确什么是泛域名。所谓泛域名&#xff0c;是指使用星号&#xff08;*&#xff09;作为子域名的占位符&#xff0c;它可以匹配任意子域名。-----而通配符在域名中&#xff0c;它可以出现在主域名的任何位置&#xff0c;它可以用于主域名和子域名的保护。 主要应用场…

XZ-Utils后门事件过程及启示

Part.01 背景 XZ-Utils&#xff08;曾经叫做LZMA Utils&#xff09;是一款开源的无损压缩命令行工具&#xff0c;是用C语言编写的跨平台工具&#xff0c;可以用于类Unix系统和Windows系统。在多数情况下&#xff0c;xz的压缩率要好过gzip和bzip2&#xff0c;解压速度也快过bz…

算法学习笔记——专题拓展2:数组双指针经典习题

关于数组的技巧有&#xff1a;双指针(快慢指针&#xff08;时差、位差&#xff09;&#xff09; 例题1&#xff1a;合并两个有序数组 代码&#xff1a;逆向双指针&#xff0c;可以不用重开数组&#xff0c;如果是正向的&#xff0c;需要重开一个数组腾空间。 class Solution …

图书借阅系统开发笔记

图书借阅系统开发介绍及心得 项目已开源到 github https://github.com/Qiu-JW/books-manage-systemgitee https://gitee.com/qiu-jw/books-manage-system 技术栈 前端 HTML5、CSS、JS、jQuery、axios、bootstrap 后端 servlet、JSP、JDBC 数据库 MySQL 项目采用mvc模式构成 …

Java的数组定义和使用

目录 1.前言 2.数组的概念 3.在Java中的创建和初始化 3.1数组的创建 3.2数组的初始化 4.关于使用 4.1数组元素的访问 4.2数组的遍历 4.3length和length()的区别 5.数组其实是引用类型数据 5.1初始JVM的内存分布 5.2基本类型变量与引用类型变量的区别 5.3关于null的认识 5.4设计…

手眼标定(外参)

1. 传统使用张正友相机标定,角点检测 //张正友相机标定,角点检测 for(int i=1;i<=images_number;i++){Mat image=imread(images_path+to_string(i)+String("/color.jpg"));Mat output=image.clone();image_size.width=image.cols;image_size.height=image.…

(34)4.17 作业课

//弓箭型 int main() { int n 0; while (scanf("%d", &n) 1) { int i 0; for (i 0; i < n; i) { int j 0; for (j 0; j < n - i; j) { printf(" &q…

工作流JBPM画图与配置

文章目录 ☃️7.1 画图☃️7.2 配置7.2.1 配置任务办理人7.2.1.1 写死的方式配置任务办理人&#xff08;不推荐&#xff09;7.2.1.2 #{}方式配置任务办理人7.2.1.3 实现接口方式配置任务办理人7.2.1.4 方法指定方式分配任务办理人 7.2.2 配置节点属性7.2.2.1 判断节点(decision…

Sourcetree安装使用(补个笔记)

Sourcetree介绍 Sourcetree是一款免费的Git图形化客户端&#xff0c;它由Atlassian开发&#xff0c;提供了跨平台的支持&#xff0c;可运行在Windows和Mac操作系统上。Sourcetree可以让开发者更方便地使用Git来管理代码&#xff0c;不需要在命令行中输入复杂的Git命令&#xf…

symfony框架介绍

Symfony是一个功能强大的PHP框架,它提供了丰富的组件和工具来简化Web开发过程。以下是一些关于Symfony的主要特点: 可重用性: Symfony提供了一系列可重用的PHP组件,这些组件可以用于任何PHP应用程序中。灵活性: Symfony允许开发者根据项目需求灵活选择使用哪些组件,而不是强…

HTML学习笔记:链接target属性

关于target的使用&#xff1a; <a href"https://www.baidu.com" target"_parent">网址链接</a>其中关于target四个特殊目标的理解&#xff0c;W3school上的解释为&#xff1a; HTML 标签的 target 属性 其中_black和_self两个属性很好理解&…