手写一个二叉堆

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写一个二叉堆相关的知识,希望对你有一定的参考价值。

手写一个二叉堆

二叉堆就是利用了二叉树的结构进行维护。

a.插入

插入一个数就是把当前数 x x x放到二叉树的尾部,然后沿着父边进行不断比较,如果比父亲大就更换,然后重复,否则退出。

void add(int x)
	a[++cnt] = x;
	int u = cnt;
	while(u>1)
		int fa = u>>1;
		if(a[u]>=a[fa]) return;
		swap(a[u],a[fa]);
		u = fa;
	

b.删除

把尾部元素与首部元素交换,然后个数减一。

再沿着较小的儿子边进行更新。

如果比儿子大就更新,重复,否则就退出。

void del()
	if(cnt<1) return;
	a[1] = a[cnt--];
	int u = 1;
	while((u<<1)<=cnt)
		int v = u<<1;
		if(v<cnt && a[v+1]<a[v]) v++;
		if(a[u]<=a[v]) return;
		swap(a[u],a[v]);
		u=v;
	

c.获取堆顶

就是第一个元素,也就是二叉树的根

int get()
	return a[1];

d.总代码

// Problem: P3378 【模板】堆
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3378
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// Date: 2022-03-02 10:40:24
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=1e6+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define db double
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

int a[N],cnt;
void add(int x)
	a[++cnt] = x;
	int u = cnt;
	while(u>1)
		int fa = u>>1;
		if(a[u]>=a[fa]) return;
		swap(a[u],a[fa]);
		u = fa;
	

void del()
	if(cnt<1) return;
	a[1] = a[cnt--];
	int u = 1;
	while((u<<1)<=cnt)
		int v = u<<1;
		if(v<cnt && a[v+1]<a[v]) v++;
		if(a[u]<=a[v]) return;
		swap(a[u],a[v]);
		u=v;
	

int get()
	return a[1];

int main()
	int n;
	scanf("%d",&n);
	while(n--)
		int op,x;
		scanf("%d",&op);
		if(op==1)
			scanf("%d",&x);
			add(x);
		
		else if(op==2)
			printf("%d\\n",get());
		
		else del();
	
	return 0;

以上是关于手写一个二叉堆的主要内容,如果未能解决你的问题,请参考以下文章

数据结构 10 基础数据结构 二叉堆 堆排序算法详解

线性表--优先队列

线性表--优先队列

P3093 [USACO13DEC]牛奶调度Milk Scheduling - 贪心+二叉堆

序列化二叉堆与二叉堆排序

二叉堆