二叉堆
1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。
堆的存储
一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。
优先队列实现最大堆最小堆
priority_queue<int> max_heap; //最大堆
priority_queue<int,vector<int>,greater<int>> min_heap; //最小堆
用堆求解数组中的第K大元素的两种方法
1.由数组创建最大堆,依次从堆中弹出k-1个元素,堆顶元素即为所求。
class Solution {
private:
priority_queue<int>max_heap;
public:
int findKthLargest(vector<int>& nums, int k) {
for(int i=0;i<nums.size();i++){
max_heap.push(nums.at(i));//at防止越界
}
for(int j=0;j<k-1;j++){
max_heap.pop();
}
int res=max_heap.top();
return res;
}
};
2.根据数组的前k个元素创建最小堆,之后从数组的第k+1个元素起,依次与堆顶元素比较,若堆顶元素小,则弹出堆顶元素,弹入数组元素,维护堆的大小始终为k,若堆顶元素大,不进行操作,遍历完数组中的元素后,堆顶元素即为所求。
class Solution {
private:
priority_queue<int,vector<int>,greater<int>>min_heap;
public:
int findKthLargest(vector<int>& nums, int k) {
for(int i=0;i<k;i++){
min_heap.push(nums.at(i));
}
for(int j=k;j<nums.size();j++){
if(min_heap.top()<nums.at(j)){
min_heap.pop();
min_heap.push(nums.at(j));
}
}
int res=min_heap.top();
return res;
}
};