6.二叉堆實現演算法
剛才聊了一會天,思路有點亂了,努力整理了一下!!!
二叉堆其實就是像生成樹一樣的方式:
其中還是有一些很nice的約束,就拿其中一個三角節點來看,要求父節點的值一定要大於兩個子節點的值,然後為了滿足這個約束,下面就產生了一些約束生成的虛擬碼:
演算法虛擬碼:
MAX-HEAPIFY(A,I)
1. l <- LEFT(i) //其中 i,l,r都為上述圖片中圓圈外的陣列標號,這裡將 l 賦值為 i 標號數值為父節點的左子節點標號
2. r <-RIGHT(I) //將 r 賦值為 i 標號數值為父節點的右子節點標號
3. if l <-heap-size[A] and A[l] >A[i] //其中heap-size[A]為該陣列的總個數]
4. then largest <- l //如果左節點數值大於父節點數值,就將子節點標號記錄下
5. else largest <- i //如果子節點數值不大於父節點數值,就還是記錄父節點標號
6. if r <=heap-size(A) and A[r] >A[largest] //將右節點的數值與現任最大數值的節點進行比較
7. then largest <- r //如果大於原最大值,就記錄下此時的標號
8. if largest != i //如果最大值所在的標號不是原本父節點的標號,就將父節點數值與最大值所在標號數值進行交換
9. then exchange A[i] <- A[largest]
10. MAX-HEAPIFY(A,largest)
(將陣列轉化為二叉堆形式)演算法虛擬碼:
BUILD-MAX-HEAP(A)
1. heap-size[A] <- length[A]
2. for i <- length[A]/2 downto 1 //這裡有個很有趣的東西,length[A]/2之後得到的標號總是位於最後一個三角節點的父節點標號
3. do MAX-HEAPIFY(A,i)
(這裡還是從底層開始建立二叉堆,其實本質上還是利用了遞迴的方法進行氣泡排序,每次冒出最大值)
C++:
main.cpp
#include <iostream> #include<algorithm> #include<iterator> #include<functional> using namespace std; int main(){ int h[]={4,1,3,2,16,9,10,14,8,7}; make_heap(h,h+10,less<int>());//STL中擁有函式模板用來做堆建立; cout<<"max heap:"<<endl; copy(h,h+10,ostream_iterator<int>(cout," ")); cout<<endl; make_heap(h,h+10,greater<int>()); cout<<"min heap:"<<endl; copy(h,h+10,ostream_iterator<int>(cout," ")); cout<<endl; }
JAVA:
LinearList.java
public class LinearList{
public static int left(int i) { return 2*i+1;//由於陣列一開始下標為0,所以跟標號為0,再大環境中更改為陣列標號 } public static int right(int i) { return 2*i+2; } public static int parent(int i) { if(i%2==1) return i/2; return i/2-1; } public static void heapify(List<Comparable> a,int i,int heapSize,Comparator comp) { int l=left(i),r=right(i),most; if((l<heapSize)&&(comp.compare(a.get(l), a.get(i))>0)) most=l; else most=i; if((r<heapSize)&&(comp.compare(a.get(r), a.get(most))>0)) most=r; if(most!=i) { Collections.swap(a,i,most); heapify(a,most,heapSize,comp); } } public static void buildHeap(List<Comparable> a,Comparator comp) { int heapSize=a.size(); for(int i=heapSize/2;i>=0;i--) heapify(a,i,heapSize,comp); }
}
Test.java
package test;
import java.util.*;
public class Test{ public static void main(String[] args){ int h[]= {4,1,3,2,16,9,10,14,8,7},i; Vector<Integer> H=new Vector<Integer>(); for(i=0;i<10;i++) H.add(new Integer(h[i])); LinearList.buildHeap((List)H, new Greater());//比較後大的提升到父節點 System.out.println("max heap:");//最大二叉堆 System.out.println(H); LinearList.buildHeap((List)H, new Less());//比較後小的提升到父節點 System.out.println("min heap:");//最小二叉堆 System.out.println(H); } }