java實現最大堆(陣列方式)
阿新 • • 發佈:2018-11-24
最大堆、最小堆其實就是優先佇列,每次取出的元素都是最大或最小的。本部落格主要用陣列實現最大堆,最小堆的實現原理也是一樣的。當然,也可以用list集合來儲存元素,方便很多,不用事先設定容量的大小。但還是想用原生的方式來實現一下。具體的註釋已經嵌入到程式碼當中了。
package heap; //利用陣列實現最大堆 public class MaxHeap { private int[] a; //儲存元素 private int size; //當前元素的個數 public MaxHeap(int initCapacity) { a=new int[initCapacity+1]; //下標為0的放"哨兵",從1開始放堆元素 a[0]=Integer.MAX_VALUE; //建立哨兵 size=0; } //判空 public boolean isEmpty() { return size==0; } //判滿 public boolean isFull() { return size==a.length-1; } //插入節點 public boolean insert(int data) { //如果陣列滿 了,則無法插入 if(isFull()) { System.out.println("已滿,無法插入"); return false; } a[++size]=data; for(int i=size;a[i]>a[i/2];i/=2) { int t=a[i]; a[i]=a[i/2]; //父節點下移到子節點的位置 a[i/2]=t; } return true; } //刪除一個節點,並返回最大值 public int deleteMax() { //如果為空 if(isEmpty()) { System.out.println("空,無元素可刪除"); return -1; } //取出最大值 int maxValue=a[1]; int tmp=a[size--]; //將最後一個節點放在根節點位置,再和左右子樹比較 int parent=1,child=2; for(;parent*2<=size;parent=child) { child=parent*2; //左孩子 //判斷是否有右孩子,並且右孩子是否比左孩子大 if(child<size&&a[child+1]>a[child]) { child++; //child指向左右孩子的較大者 } //如果根節點比左右孩子都要大,則停止比較 if(tmp>a[child]) { break; }else { int t=a[parent]; a[parent]=a[child]; a[child]=t; } } //把最後一個節點放在parent位置 a[parent]=tmp; return maxValue; } //列印堆元素 public void print() { if(isEmpty()) { System.out.println("無元素"); return; } for(int i=1;i<=size;i++) { System.out.print(a[i]+" "); } System.out.println(); } public static void main(String[] args) { int[] b= {10,8,4,5,9,15,11,20}; MaxHeap heap=new MaxHeap(b.length); for(int i=0;i<b.length;i++) { heap.insert(b[i]); } System.out.println("插入後形成最大堆:"); heap.print(); //下面測試刪除後是否還是最大堆 for(int i=0;i<2;i++) { System.out.println("刪除元素:"+heap.deleteMax()); } System.out.println("刪除後是否還是最大堆:"); heap.print(); } }