二叉堆

二叉堆

二叉堆支持 插入,删除,查询最值的数据结构,它是一棵满足堆性质的完全二叉树,树上的每一个节点都有一个权值,若儿子小于等于父亲,那就是大根堆性质;若儿子大于父亲,则满足小根堆的性质。大根堆性质的是大根堆,小根堆性质的是小根堆
这么说,我就会了
其实二叉堆就是一个类似一种排序方法,堆排序,这种算法不难
一个节点编号i,左儿子节点2i,右儿子节点2i+1,这个知识点在初赛就学过了
既然我们说过它的操作有三种,那么我们就来详细地了解一下

插入

这个操作是最基本地,在了解这个操作的时候,一定明白堆这个数据结构是实现在数组里面的
进来一个节点v的时候,我们先把它放在数组的末尾,然后通过交换不断向上调整直至满足堆性质,时间复杂度为O(logN)

int head[size],n;
void up(int now)//大顶堆 
{
	while(now>1)
	{
		if(head[now]>head[now/2])
		{
			swap(head[now],head[now/2]);
			p/=2;
		}
		else
			break;
	}
}
void insert(int v)
{
	head[++n]=v;//存储到最后
	up(n);//向上调整 
}

查询最值

查询最值返回二叉堆顶部,直接一句话,时间复杂度为O(1)

int getop()
{
	return head[1];
}

删除

删除操作就是把堆顶从二叉堆中移除,我们把堆顶与末尾的数进行交换(其实也不是什么交换,而是覆盖),然后删除最后一个点(即删除根节点),再将堆顶点向下调整,时间复杂度为O(logN)

void down(int now)
{
	int l=now*2;
	while(l<=n)//循环代替递归 
	{
		if(l<n&&head[l]<head[l+1]) l++;
		//左右节点取最大的与其交换 
		if(head[l]>head[now])
		{
			swap(head[l],head[now]);
			now=l;//父亲变到儿子,比较难想 
			l=l*2;//下走 
		}
		else break; 
	}
}
void shanchu()
{
	head[1]=head[n];//交换 
	n--;//删除 
	down(1);
}

其实STL里面的priority_queue可以直接实现大根堆小根堆,自动进行排序,支持插入删除等一些操作,这些

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值