堆
优先级队列:
按照事先约定的优先级,可以始终高效查找并访问优先级最高数据项的数据结构
维护了数据项的一个偏序关系
操作接口
1 | size(); //报告优先级队列的规模 |
应用实例:Huffman编码树,堆
Huffman编码树:略
堆
原理:
主要求解问题:O(1)的算法在n个给定的整数中找最大值, 有限偏序集的极值必然存在,堆用来维护一个偏序关系
性质:
1.完全二叉树
2.保存有序关系. 小根堆:每个结点的值都小于其子结点的值;
大根堆: 每个结点的值都大于其子结点的值;
物理结构:
有序列表
主要操作:
==上浮操作== —当大根堆的元素变大时,该结点可能会==上浮== —O(log n)
1 | inline void up(int index){ //处于index的元素变大 |
==下沉操作==—当大根堆的元素变小时,该结点可能会==下沉== —-O(log n)
1 | inline void down(int index){ |
==插入操作==–O(log n)–在数组最末尾插入元素,再做up操作
1 | inline void insert(int x){ //插入x |
==删除操作==–O(log n)–删除第index个元素,为了不破坏堆的性质,把h[len]移动到index处,堆元素个数减一,再判断做up(index) 还是down(index)
1 | inline void delete(index ){ |
过程: 初始建堆
方法1:执行n次insert操作,时间复杂度O(n*log n)
1 | void build(){ |
方法2:执行n/2次down操作
1 | void build(){ |
堆排序
初始建堆 O(n),堆排序算法为 O(n log n)
时间复杂度:最好,最坏,平均情况相同
1 | void HeapSort(){ |
(小根堆相反)
STL中堆的使用
方法1:<queue>中的priority_que
初始化方式
1 | template<typename T, typename Container=std::vector<T>,typename Compare=std::less<T> > |
基本操作
1 | push(const T& obj);// 将obj的副本放到容器的适当位置,这通常会包含一个排序操作。 |
使用
1.最基本的使用方法,对于一串数字建堆(默认为大根堆)
1 | priority_queue<int> heap; |
2.自定义
- 使用std::greater 和 std::less
- std::greater和std::less原理解析
1 | priority_queue<int,vector<int>, greater<int> > qi2;//最小堆 |
使用自定义的cmp类,重载operator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17struct Node{
int x;
int y;
int val;
Node(int a,int b,int valin):x(a),y(b),val(valin){}
};
struct cmp{
bool operator()(const Node& a, const Node& b){
return a.val<b.val;//大根堆
}
}
priority_queue<Node,vector<Node>, cmp> heap;//建堆
heap.pop();//出堆
heap.push();//入堆
heap.top(); //获取堆顶元素
方法2:利用vector
这种法法需要#include<algorithm>
#include <functional>
1 | vector<int> a; |