1. 程式人生 > >6.二叉堆實現演算法

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);     } }