java實現最大堆及堆排序__java

來源:互聯網
上載者:User
最大堆 最大堆資料結構是一棵完全二叉樹( 分葉節點只能出現在最下層和次下層,並且最下面一層的結點都集中在該層最左邊的若干位置的二叉樹)。
因為完全二叉樹的性質,因此我們用數組來儲存樹的節點,從上到下,從左至右,按序存在數組,而且子節點的值得小於等於父節點的值。因此堆的根節點是數組中的最大值,這即是最大堆。最大堆經常用於實現優先隊列。舉個栗子:比如英雄聯盟或王者榮耀中的英雄在他的攻擊範圍內,他會優先攻擊更重要的敵方單位,那些在他攻擊範圍內的敵方單位就在一個最大堆中,取出最大堆的根節點即最應該被優先攻擊的那個,攻擊它。當又有敵方單位進入攻擊範圍,則插入最大堆中,並維護最大堆的性質。 下面最大堆的實現以及堆排序的實現:
//實現最大堆(用數組來存放完全二叉樹中的節點,從上到下,從左至右排序,按序存在數組,子節點的值小於等於父節點的值)public class Heap {private int[] data;private int count; //當前節點數private int capacity; //容量public Heap(int capacity) {this.data=new int[capacity+1];  //因為索引0不存節點,所以長度加一this.capacity=capacity;this.count=0;}//將一個無序數組構造成一個最大堆          相當於堆排序public Heap(int[] arr,int n){data=new int[n+1];capacity=n;for(int i=0;i<n;i++){data[i+1]=arr[i];}count=n;for(int i=count/2;i>=1;i--){  //i=count/2:i是最後一個葉子節點的父節點(最後一個非葉子節點)shiftDown(i);}}private void shiftUp(int i){while((i>1)&&(data[i/2]<data[i])){  //data[i/2]為當前節點的父節點swap(data,i,i/2);i=i/2;   //更新索引}}private void shiftDown(int k){while((2*k)<=count){     //有左子節點 int j=2*k;      //這輪迴圈,data[k]和data[j]交換位置 if((j+1)<=count&&(data[j+1]>data[j])){ //有右子節點且右邊的更大 j+=1; } if(data[k]>=data[j])  //如果父節點大於等於子節點,則停止迴圈 break; swap(data,k,j); k=j;       //k被賦為當前位置,為下次迴圈做初始化}}public int size() {return count;}public boolean isEmpty(){return count==0;}public void insert(int a){assert((count+1)<=capacity);   //防止數組越界data[count+1]=a;     //從索引1開始存count++;   shiftUp(count);  //由於可能新添加的數違背最大堆的定義,所以要重排序}public int extractMax(){      //彈出最大值,即根節點assert(count>0);int ret=data[1];swap(data,1,count);    //將最後數放到第一位置,保持完全二叉樹的結構count--;shiftDown(1);         //將第一個數移至合適位置,保持最大堆性質return ret;}public static void swap(int[] arr,int a,int b){int c=arr[a];arr[a]=arr[b];arr[b]=c;}public static void situheapsort(int[] arr,int n){     //原地堆排序(就是堆排序),從0開始存for(int i=(n-1)/2;i>=0;i--){       //i=(n-1)/2:i是最後一個葉子節點的父節點(最後一個非葉子節點)__shiftDown(arr,n,i);      //將一個完全無序的數組arr構造成最大堆}for(int i=n-1;i>0;i--){swap(arr,0,i);          //第一個即最大值與最後一個值交換__shiftDown(arr,i,0);   //把第一個較小的值放在合適位置,此時的數組長度為n-1}}public static void __shiftDown(int[] arr,int n,int k){while((2*k+1)<n){     //有左子節點 int j=2*k+1;      //這輪迴圈,arr[k]和arr[j]交換位置 if((j+1)<n&&(arr[j+1]>arr[j])){ //有右子節點且右邊的更大 j+=1; } if(arr[k]>=arr[j])  //如果父節點大於等於子節點,則停止迴圈 break; swap(arr,k,j); k=j;       //k被賦為當前位置,為下次迴圈做初始化}}public static void main(String[] args) {Heap heap=new Heap(100);System.out.print("插入的數為:");for(int i=0;i<30;i++){int rand=new Random().nextInt(100)+1;System.out.print(rand+" ");heap.insert(rand);}System.out.println();System.out.print("heap.extractMax():");while(!heap.isEmpty()){System.out.print(heap.extractMax()+" ");   //從大到小輸出}System.out.println();System.out.println("*********************堆排序*********************************");int arr[] =MAIN.geneateArrays(30);situheapsort(arr,arr.length);for(int i=0;i<arr.length;i++){System.out.print(arr[i]+" ");}}}
列印結果:


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.