【Priority】优先队列的实现和最大堆的内容
优先队列
定义
优先队列的实现:
优先队列实现 | 入队 | 出队 |
---|---|---|
有序数组 | O(N) | O(1) |
无序数组 | O(1) | O(N) |
- 堆结构是优先队列的高效实现方式。
基本操作
JAVA
PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
offer()
poll()
peek()
size()
- 和队列基本操作一样
C++:
priority_queue<Type, Container, Functional>
top()
empty()
size()
push() 插入到队尾并排序
emplace() 原地构造一个元素并插入队列
pop()
swap()
- Type是数据类型, Container是容器类型(必须是用数组实现的容器,如vector,deque等等,但不能是list), Functional是比较方式。
//升序队列,小顶堆
priority_queue <int,vector<int>,greater<int> > q;
//降序队列,大顶堆
priority_queue <int,vector<int>,less<int> >q;
最大堆
定义
最大堆是一颗完全二叉树,并且其父节点一定大于或等于子节点值。
其父节点和子节点下标关系:
parent[i]
= i / 2
childleft = 2 * i
child right = 2 * i + 1
为了操作方便,堆的下标一般从1开始。
基本操作
-
查看堆顶元素
(即根节点元素):Top() -
插入元素
:push()
将一个值逐层向上交换到合适的位置来保持堆定义的操作称上浮
。
移除堆中元素
:pop()
将一个值逐层向下交换到合适的位置来保持堆定义的操作称下沉
。
构建堆
| Heapify
实现方式:遍历数组,上浮
操作。O(NlogN)
遍历数组,下沉
操作。O(N)
,省去所有叶子结点的操作,故常用。
5.堆排序
| Heap Sort
1. 先将首尾元素交换,然后去除尾元素,最后将新的首元素执行下沉操作。
2. 反复执行1,直到完成排序。
- push和pop都是在堆末尾执行,因为堆结构是完全二叉树,完全二叉树是用数组保存,操作数组末尾的时间复杂度为O(1),故在堆末尾执行。