当前位置: 首页 > news >正文

【数据结构】堆和集合笔记

  1. 自己写一个堆

首先,明确一下,为什么需要堆?

=>考虑插入,删除,查找的效率。

数组,查找,最快是二分查找O(lgN)。但查找完如果要做什么操作,比如删除,就要挪动元素了。所以合起来效率是O(lgN)+O(N)=O(N)

二叉树,看起来是O(lgN),但之前写树的时候有说过,链表是不是树?是树的退化形态,每个结点都有小于等于一个的儿子。这个时候查找的效率是O(lgN)了。之前说,查找之后万一要做什么操作,树就可能不是完全二叉树,即查找效率为O(lgN)。

能不能试图用平衡二叉树?不能,rotate非常麻烦。

=>所以尝试保持一颗完全二叉树=>给这棵树起名堆。

接下来考虑需要用什么基础的数据结构存储。

需要指针吗?

完全二叉树是每一个结点要么没有儿子,要么有两个儿子,在堆里只有最后一个有儿子的父节点可以只有左儿子。所以完全可以用数组表示。

假如链表下标从1开始,2和3是它的子节点,2/2=1,3/2=1,父节点访问也很方便。

  1. 初始化

表示这棵树需要几个数据:总容量,现在有多少元素,以及存放元素的数组。

初始化需要提供总容量。

  1. 插入元素

为确保是一个完全二叉树,插在最后。

堆需要确保一件事情,小元素在上,大元素在下。所以需要向上进行一次数据交换,寻找插入值的最终位置。

注意,这里说的是寻找,不需要真的交换,只需要挪动不符合要求的元素,找到插入值的最终位置赋值即可。

  1. 删除元素

删除一定是删最小的。其余和插入一样。

为确保是一个完全二叉树,将最后一个元素和被删除的第一个元素交换,然后向下寻找最终位置。

4. 一个数组的插入

为了保证堆的性质,插入数组后需要排序。

思考一下,哪些需要排序?

如果向下调整位置,则叶子结点不需要轮。如果向上调整位置,则根节点不需要轮。

效率为重,叶子结点最多,如果向上调整,则叶子结点需要轮的距离最远。而事实上,叶子结点又占了树结点的很大一部分。

所以我们选择向下调整。

完整代码(包括测试)

#include<iostream>
using namespace std;
class h{
private:int *nums;int capacity;int l;
public:h(){capacity=0;}void init(int c=1){capacity=c;l=0;nums=new int [c+1];}void printh(){for(int i=1;i<=l;i++){cout<<nums[i]<<" ";}cout<<endl;}int isfull(){if(capacity==l){return 1;}return 0;}void moveup(int k){int tempnum=nums[k];int i=k;for(i;tempnum<nums[i/2]&&i>1;i/=2){nums[i]=nums[i/2];}nums[i]=tempnum;}int insert(int n){if(isfull()){return 0;}nums[l+1]=n;l++;moveup(l);return 1;}int isempty(){if(l==0){return 1;}return 0;}void movedown(int k){int tempnum=nums[k];int i=k;while(i*2<=l){int child=i*2;if(child<l){if(nums[child]>nums[child+1]){child++;}}if(nums[child]<tempnum){nums[i]=nums[child];i=child;}else{nums[i]=tempnum;return ;}}nums[i]=tempnum;return ;}int remove(){if(isempty()){return 0;}nums[1]=nums[l];l--;movedown(1);return 1;}void buildheap(int *a,int len,int c=0){if(len>c){c=len;}init(c);l=len;for(int i=0;i<len;i++){nums[i+1]=a[i];}for(int i=len/2;i>=1;i--){movedown(i);}}
};
int main(){int a[6]={10,50,60,5,30,20};h h1;h1.buildheap(a,6);h1.printh();
}

2. c++的堆

堆在queue中,叫priority_queue,默认是大顶堆,即树根是最大的元素,可以执行一下验证。

所以插入是push,查看堆顶元素是top(),弹出堆顶是pop()。

#include<iostream>
#include<queue>
using namespace std;
int main(){priority_queue<int>q1;int a[6]={111,222,333,11,22};for(int i=0;i<5;i++){q1.push(a[i]);}cout<<q1.top()<<endl;q1.pop();cout<<q1.top()<<endl;
}

堆额外有一种方法让其变为小顶堆,即提供一个容器,前提是这个容器支持从小到大排序,比如vector。

可以借助以下程序验证。

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
int main(){priority_queue<int,vector<int>,greater<int> >q1;int a[5]={111,222,333,11,22};for(int i=0;i<5;i++){q1.push(a[i]);}for(int i=0;i<5;i++){cout<<q1.top()<<endl;q1.pop();}
}

3. c++的集合

集合就是set嘛,之前刷题用了好多次了。

注意三点:

  1. set默认从小到大排序(因为底层实现是红黑树,类似AVL树)

  1. set.insert()也可以插入集合,方法详见下方实验代码

  1. 对于力扣中要求返回vector但你用set做了,只要返回{set.begin(), set.end()}即可

可以用以下代码验证set

#include<iostream>
#include<set>
using namespace std;
int main(){set<int>s1;int a1[3]={333,222,111};for(int i=0;i<3;i++){s1.insert(a1[i]);}for(auto x:s1){cout<<x<<" ";}cout<<endl;set<int>s2;s2.insert(666);s2.insert(555);s1.insert(s2.begin(),s2.end());for(auto x:s1){cout<<x<<" ";}cout<<endl;
}

相关文章:

【数据结构】堆和集合笔记

自己写一个堆首先&#xff0c;明确一下&#xff0c;为什么需要堆&#xff1f;>考虑插入&#xff0c;删除&#xff0c;查找的效率。数组&#xff0c;查找&#xff0c;最快是二分查找O(lgN)。但查找完如果要做什么操作&#xff0c;比如删除&#xff0c;就要挪动元素了。所以合…...

java LinkedList 源码分析(通俗易懂)

目录 一、前言 二、LinkedList类简介 三、LinkedList类的底层实现 四、LinkedList类的源码解读 1.add方法解读 : 〇准备工作 。 ①跳入无参构造。 ②跳入add方法。 ③跳入linkList方法。 ④增加第一个元素成功。 ⑤向链表中添加第二个元素。 2.remove方法解读 : 〇准备工…...

Vue中实现路由跳转的三种方式详细分解

vue中实现路由跳转的三种方式 目录 vue中实现路由跳转的三种方式 一、使用vue-router 1.下载vue-router模块到当前工程 2.在main.js中引入VueRouter函数 3.添加到Vue.use()身上 – 注册全局RouterLink和RouterView组件 4.创建路由规则数组 – 路径和组件名对应关系 5…...

全国自学考试03708《中国近现代史纲要》重点复习精要

1. 西方列强的殖民扩张和鸦片战争的影响。&#xff08;两面性&#xff09; &#xff1a;反面—破坏了了中国的小农经济&#xff0c;是中国由封建社会转变为两半社会。 --一系列不公平条约&#xff0c;破坏了中国主权领土完整。 --压迫中国人民&#xff0c;给中国人民带来了巨大…...

数据库面试题——锁

了解数据库的锁吗&#xff1f; 锁是数据库系统区别于文件系统的一个关键特性&#xff0c;锁机制用于管理对共享资源的并发访问。 InnoDB下两种标准行级锁&#xff1a; 共享锁&#xff08;S Lock&#xff09;&#xff0c;允许事务读一行数据。 排他锁&#xff08;X Lock&…...

Python笔记 -- 文件和异常

文章目录1、文件1.1、with关键字1.2、逐行读取1.3、写入模式1.4、多行写入2、异常2.1、try-except-else2.2、pass1、文件 1.1、with关键字 with关键字用于自动管理资源 使用with可以让python在合适的时候释放资源 python会将文本解读为字符串 # -*- encoding:utf-8 -*- # 如…...

蓝桥杯刷题冲刺 | 倒计时24天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.修剪灌木2.统计子矩阵1.修剪灌木 题目 链接&#xff1a; 修剪灌木 - 蓝桥云课 (lanqiao.cn) 找…...

真正理解微软Windows程序运行机制——什么是消息

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天说说Windows程序的运行机制。经常被问到MFC到底是一个什么技术&#xff0c;为了解释这个我之前还写过帖子&#xff0c;但是很多人还是不理解。其实这没什么&#xff0c;我在学生时代也被这个问题困绕过。…...

HTTP 缓存的工作原理

缓存是解决http1.1当中的性能问题主要手段。缓存可能存在于客户端浏览器上&#xff0c;也可以存在服务器上面&#xff0c;当使用过期缓存可能给用户展示的是错误的信息而导致一些bug。 HTTP 缓存&#xff1a;为当前请求复用前请求的响应 • 目标&#xff1a;减少时延&#xff1…...

RK3568在Android上进行驱动模块开发(源码外)

文章目录 前言一、ARCH架构二、编译器三、建立自己的Makefile文件总结前言 本文记录在驱动开发时,由于编译内核时间较长,经常会选择单独编译一个模块,这里主要讲解,makefile文件如何编写(主要是编译器和架构) 提示:以下是本篇文章正文内容,下面案例可供参考 一、ARCH…...

操作技巧 | 在Revit中借用CAD填充图案的方法

在建模过程中&#xff0c;有时需要达到多种填充效果&#xff0c;而CAD中大量的二维填充图案&#xff0c;便是最直接的资源之一。 使用 填充图案之前 使用 填充图案之后 其中要用到主要命令便是对表面填充图案的添加与编辑 简单效果 如下 模型填充与绘图填充 区别 模型填…...

Java的二叉树、红黑树、B+树

数组和链表是常用的数据结构&#xff0c;数组虽然查找快&#xff08;有序数组可以通过二分法查找&#xff09;&#xff0c;但是插入和删除是比较慢的&#xff1b;而链表&#xff0c;插入和删除很快&#xff08;只需要改变一些引用值&#xff09;&#xff0c;但是查找就很慢&…...

昨天某读者拿到华为OD岗位offer,今天来分享一下经验,包含华为OD机试

来自读者投稿&#xff0c;已经拿到华为 OD 开发岗位 offer&#xff0c;询问了一些问题&#xff0c;下面是他的一些经验。 文章目录华为 OD 投递简历华为 OD 机试分数OD 机试通过之后&#xff0c;收到综合测评OD 技术面&#xff08;时长 1 小时左右&#xff09;主管/HR 面试&…...

树的遍历方式(前中后,层序遍历,递归,迭代,Morris遍历)-----直接查询代码

目录 一.前序遍历 1.递归 2.栈迭代 3.Morris遍历 二.中序遍历 1.递归 2.栈迭代 3.Morris遍历 三.后序遍历 1.递归 2.栈迭代 3.Morris遍历 四.前中后序的统一迭代法 1.前序遍历 2.中序遍历 3.后序遍历 五.层序遍历 1.队列迭代 2.之字形层序遍历 3.锯齿形层序…...

Docker Registry部署镜像私有仓库及鉴权认证

文章目录一、Docker Registry是什么&#xff1f;二、Docker Registry部署私有仓库2.1、Docker Registry安装2.2、Docker Registry配置2.3、启动Docker Registry2.4、Docker客户端配置2.5、向Docker Registry上传和下载镜像三、Docker Registry鉴权和认证3.1、基本认证3.2、Bear…...

stm32外设-中断详解

0. 写在最前 本栏目笔记都是基于stm32F10x 1. 中断是啥&#xff1f; 什么是中断&#xff1a;CPU在处理某一事件A时&#xff0c;发生的另外某一事件B请求CPU去处理&#xff08;产生了中断&#xff09;&#xff0c;随后CPU暂时中断当前正在执行的任务&#xff0c;去对事件B进行处…...

第十四届蓝桥杯三月真题刷题训练——第 13 天

目录 第 1 题&#xff1a;特殊日期 问题描述 答案提交 运行限制 代码&#xff1a; 思路&#xff1a; 第 2 题&#xff1a;重合次数 问题描述 答案提交 运行限制 代码&#xff1a; 第 3 题&#xff1a;左移右移 问题描述 输入格式 输出格式 样例输入 样例输出…...

webgl_gpgpu_birds 样例分析

webgl_gpgpu_birds 是一个 three.js 的官方样例&#xff0c;这个例子模拟了鸟群的运动&#xff0c;是一个群组动画&#xff0c;并且动画的帧率也很高&#xff1b;鸟群的运动很自然&#xff0c;非常值得研究。类似的群组动画还有鱼群&#xff0c;boid是‘类鸟群’的英文 大概两…...

以业务行为驱动的反入侵安全能力建设

0x0 背景 最近听到一些甲方安全领域的专家分享了部分安全建设的经验&#xff0c;对安全运营下的反入侵技术能力建设有了些新的看法&#xff0c;依靠单个/多个异构的安全产品的关联能力形成的安全中台并不能在实际的攻防对抗当中占据主动地位&#xff0c;且很容易达到一个天花板…...

Unity3d C#使用DOTween插件的Sequence实现系列动画OnComplete无效和颜色设置无效的问题记录

前言 最近在弄一个文字动画效果的动画&#xff0c;使用了DOTween插件的Sequence来实现&#xff0c;主要就是对一个Text进行的文字打字、缩放和颜色设置等动画&#xff0c;功能是先对Text实现打字的动画&#xff0c;打字完成后&#xff0c;延时几秒对文字进行缩小、颜色变淡&am…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...