數據結構之堆
堆是什麼?堆是一種特殊的完全二叉樹,就像下面這棵樹一樣
最小堆的特點:所有父節點的值都比子節點要小!相反
最大堆得特點:所有父節點的值都比子節點要大!
如何構造堆呢?
99,5,36,7,22,17,46,12,2,19,25,28,1,92 對於這樣一串數字來說,首先建立一個數組a,長度爲15,(a[0]不存數字,從下標1開始)
首先所有的葉子節點都是滿足最小堆的條件的,因爲他們沒有子節點,因此應該從n/2開始(n爲數字的個數,而不是數組的長度,這裏等於14),判斷是否滿足堆得性質,如果不滿足,則調整,Java代碼如下:
public class Heap {
public static void main(String[] args) {
int[] a=new int[]{0,99,5,36,7,22,17,46,12,2,19,25,28,1,92};
for(int i=14/2;i>=1;i--)
topToDown(a, i);
for(int i=1;i<a.length;i++)
System.out.print(a[i]+" ");
}
public static void topToDown(int[] a,int index){
if(index>=a.length||2*index>=a.length) return ;
if(2*index+1>=a.length){
if(a[index]<a[2*index])
return ;
else{
int temp=a[2*index];
a[2*index]=a[index];
a[index]=temp;
topToDown(a, 2*index);
}
}else{
if(a[index]<a[2*index]&&a[index]<a[2*index+1])
return ;
else{
int temp;
if(a[2*index]>a[2*index+1]){
temp=a[2*index+1];
a[2*index+1]=a[index];
a[index]=temp;
topToDown(a, 2*index+1);
}else{
temp=a[2*index];
a[2*index]=a[index];
a[index]=temp;
topToDown(a, 2*index);
}
}
}
}
}
如何利用堆呢?
堆可以用來求最大最小值,也可以排序數組,下面舉個例子
題目描述
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4。
求最小的K個數,解題過程如下:利用數組的前K個數構造一個堆,並且維護成爲最大堆,然後遍歷數組的第k+1個數,如果比堆頂元素大,則丟棄,繼續遍歷k+2個數,如果比堆頂元素小,則將堆頂元素置換爲這個數,並且維護堆的性質,再遍歷k+2個數。這樣依次這樣依次下去,當數組遍歷完的時候,堆中的元素就是最小的K個數!
Java代碼實現如下
public class Heap {
public static void main(String[] args) {
int[] a=new int[]{4,5,1,6,2,7,3,8};
int[] heap=new int[5];
for(int i=0;i<4;i++){
heap[i+1]=a[i];
}
for(int i=8/2;i>=1;i--)
maxHeap(heap, i);
for(int i=4;i<a.length;i++){
if(a[i]<heap[1]){
heap[1]=a[i];
maxHeap(heap, 1);
}
}
for(int i=1;i<heap.length;i++)
System.out.print(heap[i]+" ");
}
public static void maxHeap(int[] heap,int index){
if(index>=heap.length||2*index>=heap.length) return ;
if(2*index+1>=heap.length){
if(heap[index]<heap[2*index]){
int temp=heap[2*index];
heap[2*index]=heap[index];
heap[index]=temp;
maxHeap(heap, 2*index);
}else{
return ;
}
}else{
if(heap[index]>heap[2*index]&&heap[index]>heap[2*index+1])
return ;
else{
int temp;
if(heap[2*index]>heap[2*index+1]){
temp=heap[2*index];
heap[2*index]=heap[index];
heap[index]=temp;
maxHeap(heap, 2*index);
}else{
temp=heap[2*index+1];
heap[2*index+1]=heap[index];
heap[index]=temp;
maxHeap(heap, 2*index+1);
}
}
}
}
}