堆
- 最大堆、最小堆
- 最大堆可用于优先队列
- STL中 :priority_queue就是最大堆
- 堆排序
STL中有关堆的操作
- Heap:
- push_heap:Push element into heap range (function template )
- pop_heap:Pop element from heap range (function template )
- make_heap:Make heap from range (function template )
- sort_heap:Sort elements of heap (function template )
- is_heap:Test if range is heap (function template )
- is_heap_until:Find first element not in heap order (function template )
- 举例:
#include <iostream> // std::cout
#include <algorithm> // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap
#include <vector> // std::vector
using namespace std;
int main () {
int myints[] = {10,20,30,5,15};
vector<int> v(myints,myints+5);
make_heap (v.begin(),v.end());
cout << "initial max heap : " << v.front() << '\n';
cout << "initial:";
for (unsigned i=0; i<v.size(); i++) cout << ' ' << v[i]; cout<<'\n';
pop_heap (v.begin(),v.end());
cout << "pop_heap :";
for (unsigned i=0; i<v.size(); i++) cout << ' ' << v[i]; cout<<'\n';
v.pop_back();
cout << "max heap after pop : " << v.front() << '\n';
cout << "after pop_back";
for (unsigned i=0; i<v.size(); i++) cout << ' ' << v[i]; cout<<'\n';
v.push_back(99); push_heap (v.begin(),v.end());
cout << "max heap after push: " << v.front() << '\n';
sort_heap (v.begin(),v.end());
cout << "final sorted range :";
for (unsigned i=0; i<v.size(); i++) cout << ' ' << v[i]; cout << '\n';
return 0;
}
OUTPUTS:
initial max heap : 30
initial: 30 20 10 5 15
pop_heap : 20 15 10 5 30
max heap after pop : 20
after pop_back 20 15 10 5
max heap after push: 99
final sorted range : 5 10 15 20 99
Leetcode习题
The Skyline Problem
My C++ code using one priority queue (812 ms)vector<pair<int, int>> getSkyline(vector<vector<int>>& buildings) { vector<pair<int, int>> res; int cur=0, cur_X, cur_H =-1, len = buildings.size(); priority_queue< pair<int, int>> liveBlg; while(cur<len || !liveBlg.empty()){ cur_X = liveBlg.empty()? buildings[cur][0]:liveBlg.top().second; if(cur>=len || buildings[cur][0] > cur_X){ while(!liveBlg.empty() && ( liveBlg.top().second <= cur_X) ) liveBlg.pop(); } else{ cur_X = buildings[cur][0]; while(cur<len && buildings[cur][0]== cur_X){ liveBlg.push(make_pair(buildings[cur][2], buildings[cur][1])); cur++; } } cur_H = liveBlg.empty()?0:liveBlg.top().first; if(res.empty() || (res.back().second != cur_H) ) res.push_back(make_pair(cur_X, cur_H)); } return res; }
-
vector<int> maxSlidingWindow(vector<int>& nums, int k) { if(nums.empty()) return {}; vector<int> res; int n=nums.size()-k+1; if(n>0){ for(int i=0;i<n;i++) res.push_back(*max_element(nums.begin()+i,nums.begin()+i+k)); } return res; }
Kth Largest Element in an Array
int findKthLargest(vector<int>& nums, int k) { make_heap(nums.begin(),nums.end()); for(int i=0;i<k-1;i++) { pop_heap(nums.begin(),nums.end()); nums.pop_back(); } return nums.front(); }
class MedianFinder {
private:
priority_queue<long> small, large;
public:
// Adds a number into the data structure.
void addNum(int num) {
small.push(num);
large.push(-small.top());
small.pop();
if (small.size() < large.size()) {
small.push(-large.top());
large.pop();
}
}
// Returns the median of current data stream
double findMedian() {
return small.size() > large.size()
? small.top()
: (small.top() - large.top()) / 2.0;
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf;
// mf.addNum(1);
// mf.findMedian();
堆排序
- 堆数据结构是用数组保存的完全二叉树实现
- 保持堆:时间复杂度O(logN)
- 维护堆得过程是逐级向下展开的
/* @ index:数组A中的索引号
* @ length:维护的堆得大小(不是A的大小)*/
void maxHeapify(vector<int>& A,int index, int length){
int left=2*index+1;
int right=2*index+2;
int largest=index;
if(left<length&&A[left]>A[largest]) largest=left;
if(right<length&&A[right]>A[largest]) largest=right;
if(largest!=index) {
swap(A[largest],A[index]);
maxHeapify(A,length,largest);
}
}
- 建堆:时间复杂度O(N)
- 建堆的过程是逐级向上展开
void buildHeap(vector<int> &A){
int len=A.size();
//0~len/2-1结点为非叶结点
for(int i=len/2;i>=1;i--)
maxHeapify(A,len,i-1);
}
- 排序:时间复杂度O(NlogN)
/* 根据最大堆的性质,依次将头元素和尾元素交换,然后维护尾结点之前的数组为最大堆*/
void heapSort(vector<int> &A){
int len=A.size();
for(int i=len-1;i>=1;i--){
swap(A[0],A[i]);
maxHeapify(A,i,0);
}
}
- 堆排序复杂度分析
- 最佳时间复杂度:O(NlogN)
- 平均时间复杂度:O(NlogN)
- 最坏时间复杂度:O(NlogN)
- 应用场合:
- 海量数据中查询TopK大(小)的数
- 优先队列
- 用优先队列实现栈
- 用优先队列实现FIFO队列:转载from
#include "iostream"
#define MAX 0x7fffffff
using namespace std;
//heap_size小于等于20
int B[20],heap_size=0;
int counter=0;
int parent(int i){
return i/2;
}
int left(int i){
return 2*i;
}
int right(int i){
return 2*i+1;
}
void decrease_Key(int A[],int i,int key){
int temp;
A[i] = key;
while(i > 1 && A[parent(i)] < A[i]){
temp = A[i];
A[i] = A[parent(i)];
A[parent(i)] = temp;
i = parent(i);
}
}
void insert_MinHeap(int A[],int key){
heap_size++;
A[heap_size] = MAX;
decrease_Key(A,heap_size,key);
}
void minHeapify(int A[],int i){
int l,r;
l = left(i);
r = right(i);
int smallest;
if(l <= heap_size && A[i] < A[l])
smallest = l;
else
smallest = i;
if(r <= heap_size && A[smallest] < A[r])
smallest = r;
int temp;
if(smallest != i){
temp = A[i];
A[i] = A[smallest];
A[smallest] = temp;
minHeapify(A,smallest);
}
}
int extract_MinHeap(int A[]){
if(heap_size > 0)
{
int x = A[1];
cout<<heap_size<<endl;
A[1] = A[heap_size];
heap_size--;
minHeapify(A,1);
return x;
}
else
return -1;
}
void enQueue(int A[],int data){
B[counter] = data;
insert_MinHeap(A,counter);
counter++;
}
int deQueue(int A[]){
int i = extract_MinHeap(A);
if(i < 0)
return MAX;
return B[i];
}
int main(){
int A[20];
enQueue(A,12);
enQueue(A,45);
enQueue(A,34);
cout<<deQueue(A)<<endl;
cout<<deQueue(A)<<endl;
cout<<deQueue(A)<<endl;
if(heap_size > 0)
{
cout<<deQueue(A)<<endl;
}
return 0;
}
- 用优先队列对k的有序数组进行合并
struct compare {
bool operator()(const ListNode* l, const ListNode* r) {
return l->val > r->val;
}
};
ListNode *mergeKLists(vector<ListNode *> &lists) { //priority_queue
priority_queue<ListNode *, vector<ListNode *>, compare> q;
for(auto l : lists) {
if(l) q.push(l);
}
if(q.empty()) return NULL;
ListNode* result = q.top();
q.pop();
if(result->next) q.push(result->next);
ListNode* tail = result;
while(!q.empty()) {
tail->next = q.top();
q.pop();
tail = tail->next;
if(tail->next) q.push(tail->next);
}
return result;
}