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
代表大顶堆或小顶堆,缺省值为大顶堆。
作者不会咕,等更新吧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话