Data Structure - Heap(堆)

Data Structure - Heap(堆)

定义

是一棵
每个节点都有权值
每个节点都大于等于/小于等于其父节点的权值

堆的分类

习惯上,不加限定提到「堆」时往往都指二叉堆

堆专题选讲——二叉堆

结构

从二叉堆的结构说起,它是一棵完全二叉树,每个结点都有权值。

性质

父亲的权值不小于儿子的权值称为小根堆。同样的,我们可以定义大根堆。本文以小根堆为例。

操作——插入

插入操作是指向二叉堆中插入一个元素,
要保证插入后也是一棵完全二叉树。
最简单的方法就是,最下一层最右边的叶子之后插入
如果最下一层已满,就新增一层。

但是,插入之后可能会不满足堆性质

上浮:如果这个结点的权值大于它父亲的权值,
就交换,重复此过程直到不满足或者到根。
可以证明,插入之后向上调整后,
没有其他结点会不满足堆性质。
上浮的时间复杂度是 $O(\log n)$ 的。

操作——删除

删除操作指删除堆中最大的元素,即删除根结点

但是如果直接删除,则变成了两个堆,难以处理。

我们通常采用的方法是,把根结点和最后一个结点直接交换
于是直接删掉(在最后一个结点处的)根结点,但是新的根结点可能不满足堆性质……

下沉:在该结点的儿子中,找一个最大的,与该结点交换,重复此过程直到底层。
可以证明,删除并下沉后,
没有其他结点不满足堆性质。
时间复杂度 $O(\log n)$。

操作——修改权值

很显然,直接修改后,上浮一次即可,时间复杂度为 $O(\log n)$。

模板

template<typename _Tp,typename _Compare=less<vector<_Tp>>>
class binary_heap{
	protected:
		vector<_Tp> heap;
	public:
		void insert(const _Tp _val){
			heap.push_back(_val);
			push_heap(heap.begin(),heap.end(),_Compare());
		}
		void erase(){
			heap.pop_back();
			pop_heap(heap.begin(),heap.end(),_Compare());
		}
		_Tp head() const {
			return heap.front();
		}
		bool empty(){
			return heap.empty();
		}
		size_t size(){
			return heap.size();
		}
		size_t length(){
			return heap.length();
		}
};

或者下载文件

STL中的二叉堆——优先队列

优先队列底层使用堆实现,实际上相当STL中的二叉堆。
使用方法:

priority_queue<typename _Tp,
typename _Sequence = vector<_Tp>,
typename _Compare = less<typename
_Sequence::value_type>>

其中_Tp代表数据类型,_Sequence代表容器类型,_Compare代表大顶堆小顶堆缺省值为大顶堆

作者不会咕,等更新吧

posted @   Jadejunxi  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示