完全二叉树中,任意节点的关键词大于等于它的两个子节点的关键词,这样的数据结构称为堆。也就是说,根节点保存的元素为最大元素(大根堆)。
一般我们将堆映射到数组上,父节点 i 左子节点 2i+1 右子节点 2i+2 。
堆排序的过程:
1.将待排序数组,构建为堆,此时根节点(数组首部)即为最大值
2.将最大值与叶子节点(数组尾部),交换位置,也就是说我们在 0 ~ i内已经找到了最大值,
3.下一步再在 0 ~ i-1 上,构建堆
4.循环往复,直到所有节点都处于合适的位置上
我们知道了堆排的过程,那么如何实现构建堆、将无序数组调整为堆结构的呢?
1.每次从最后一棵子树开始,从后往前调整,整个数组长为size 那么最后一个非叶子节点,也就是最后一棵子树的根节点索引可以记为 |size/2| -1
2.比较其左右节点与根节点的大小,如果比根节点大,就交换位置
3.再向前遍历到整棵树的根节点,最终整棵树上的根节点,为最大值
4.我们将最大值与末尾值交换,排除最大值后,继续进行堆重构操作
优先队列的本质是堆,但它具有队列的所有操作特性,与普通队列不同的地方就是出队的时候按照优先级顺序出队,这个优先级即最大堆或最小堆的规则(即大的为top优先出队或小的为top优先出队),在队列的基础上加了个堆排序。以O(log n) 的效率查找一个队列中的最大值或者最小值,即执行堆重构一次,其中是最大值还是最小值是根据创建的优先队列的性质来决定的。
C++中优先队列语法, priority_queue<Type, Container, Functional>
//构造一个空的优先队列(此优先队列默认为大顶堆)
priority_queue<int> big_heap;
//另一种构建大顶堆的方法
priority_queue<int,vector<int>,less<int> > big_heap2;
//构造一个空的优先队列,此优先队列是一个小顶堆
priority_queue<int,vector<int>,greater<int> > small_heap;
函数
push() 它将新元素插入优先队列。
pop() 它将优先级最高的元素从队列中删除。
top() 此函数用于寻址优先队列的最顶层元素。
size() 返回优先队列的大小。
empty() 它验证队列是否为空。基于验证,它返回队列的状态。
swap() 它将优先队列的元素与具有相同类型和大小的另一个队列交换。
emplace() 它在优先队列的顶部插入一个新元素。