【数据结构】堆和集合笔记
创始人
2025-05-29 01:34:30
0
  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
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<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(childnums[child+1]){child++;}}if(nums[child]c){c=len;}init(c);l=len;for(int i=0;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
#include
using namespace std;
int main(){priority_queueq1;int a[6]={111,222,333,11,22};for(int i=0;i<5;i++){q1.push(a[i]);}cout<

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

可以借助以下程序验证。

#include
#include
#include
using namespace std;
int main(){priority_queue,greater >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<

3. c++的集合

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

注意三点:

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

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

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

可以用以下代码验证set

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

相关内容

热门资讯

工作表态发言稿 工作表态发言稿(通用6篇)  在我们平凡的日常里,用到发言稿的地方越来越多,发言稿的格式由称谓、开场...
教师的评语 教师的评语精选15篇  在日复一日的学习、工作或生活中,大家对评语都再熟悉不过了吧,评语的内容、格式...
道路养护管理制度 道路养护管理制度(通用5篇)  在当今社会生活中,我们可以接触到制度的地方越来越多,制度是在一定历史...
专业技术工作述评 专业技术工作述评  一、述评的定义  叙述和评论。述评是一种以夹叙夹议、边叙边评的方式,反映社会热点...
学校开放日的活动方案 有关学校开放日的活动方案范文(精选9篇)  为了确保活动有效开展,常常要根据具体情况预先制定活动方案...
餐厨废弃物处置管理制度 餐厨废弃物处置管理制度(精选10篇)  管理制度是对一定的管理机制、管理原则、管理方法以及管理机构设...
幼儿园考勤制度 幼儿园考勤制度一、请假的类别与期限(一)全体教职工执行签到制,一个月统计公布一次。实行按月评比检查。...
行政再审申诉书实例 行政再审申诉书实例  以下是CN人才公文网小编给大家整理收集的行政再审申诉书实例,供大家阅读参考。 ...
幼儿园安全管理制度 幼儿园安全管理制度范本(通用16篇)  为加强幼儿园的安全管理,保护幼儿安全,需要制定并实施相应的管...
业务员的提成方案介绍 业务员的提成方案介绍  业务员是指在组织中担负具体专项经济业务,如生产、计划、销售、财会、统计、物价...
设备安全管理制度 设备安全管理制度(通用22篇)  在发展不断提速的社会中,大家逐渐认识到制度的重要性,制度泛指以规则...
实验室的管理制度 实验室的管理制度(通用8篇)  在快速变化和不断变革的今天,人们运用到制度的场合不断增多,制度泛指以...
老年公寓章程 老年公寓章程范本  老年公寓是专供老年人集中居住,下面是小编给大家整理的老年公寓章程范本,供大家阅读...
机房管理制度 机房管理制度(精选16篇)  在不断进步的时代,制度的使用频率呈上升趋势,制度是维护公平、公正的有效...
车辆管理方案 车辆管理方案(精选10篇)  为保障事情或工作顺利开展,就常常需要事先准备方案,方案是综合考量事情或...
教师述职报告 【必备】教师述职报告模板汇编七篇  随着社会一步步向前发展,报告与我们愈发关系密切,报告包含标题、正...
医院实习生管理制度 医院实习生管理制度  在当下社会,大家逐渐认识到制度的重要性,制度是在一定历史条件下形成的法令、礼俗...
有限空间安全设备设施管理制度 有限空间安全设备设施管理制度(通用6篇)  在现在社会,制度对人们来说越来越重要,制度具有合理性和合...
公物管理制度 公物管理制度(精选3篇)  现如今,制度的使用频率逐渐增多,制度是要求大家共同遵守的办事规程或行动准...
仓库物料储存管理制度 仓库物料储存管理制度(通用10篇)  在当下社会,很多地方都会使用到制度,制度具有使我们知道,应该做...