堆不同于Heap,在算法中,它是一种数据结构。它存储成数组,逻辑上可以看做一个近似的完全二叉树。
最大堆的性质:父节点的值大于等于子节点的值。
最小堆的性质:父节点的值小于等于子节点的值。
下面都是基于最大堆讨论:
1. 给定一个无序数组A,维护第i个元素堆的性质算法可表示为:
MAX_HEAPITY(A, i){
l=LEFT(i)
r=RIGHT(i)
if(l<=A.heap-size and A[l]>A[i])
largest=l
else
largest=i
if(r<=A.heap-size and A[r]>A[largest])
largest=r
if(largest != i)
exchange A[i] and A[largest]
MAX_HEAPITY(A, largest)
}
时间复杂度为O(lgn)
2. 把一个无序数组A建成堆的算法:
BUILD_MAX_HEAP(A){
A.heap-size=A.length
for(i=A.length/2 to 1)
MAX_HEAPIFY(A, i)
}
建堆的时间复杂度是O(n)
3.堆排序算法
HEAPSORT(A){
BUILD_MAX_HEAP(A)
for(i=A,length to 2){
exchange A[1] with A[i]
A.heap-size=A.heap-size-1
MAX-HEAPITY(A, 1)
}
}
堆排序算法的时间复杂度为O(nlgn)
问题一:给你一个无序数组A,求最小的K个数
思路:创建一个K个数组成的最大堆,然后若堆外面的元素小于A[0],替换A[0]和该元素,并重新调整最大堆,尝试所有堆外元素后,该堆中所有元素就是最小的K个数。
代码如下:
void MAX_HEAPITY(vector<int>& A, int heapsize,int i){
int l=2*i+1;
int r=2*i+2;
int largest=i;
if(l<heapsize && A[l]>A[i])
largest=l;
if(r<heapsize && A[r]>A[largest])
largest=r;
if(largest!=i){
int temp=A[i];
A[i]=A[largest];
A[largest]=temp;
MAX_HEAPITY(A,heapsize,largest);
}
}
void BUILD_MAX_HEAP(vector<int>& A, int heapsize){
for(int i=heapsize/2-1;i>=0;i--){
MAX_HEAPITY(A,heapsize,i);
}
}
vector<int> findKmin(vector<int>& A, int length, int k){
if(k>=length)
return A;
BUILD_MAX_HEAP(A,k);
for(int i=k+1;i<length;i++){
if(A[i]<A[0]){
int temp=A[i];
A[i]=A[0];
A[0]=temp;
MAX_HEAPITY(A,k,0);
}
}
return A;
}