堆的向下調整(siftDown):爲了知足小堆的性質,即任意結點的值都小於其子樹中結點的值,所以須要對指定結點進行向下調整,代碼以下:api
//size是數組的大小,index是須要向下調整的元素的下標 public void siftDown(int[] array, int size, int index) { int left = (index << 1) + 1; //堆是徹底的二叉樹,若是沒有左節點,那麼一定沒有右節點,所以以左節點做爲先決條件 while(left < size) { //先假定最小的值時左節點的值 //緣由:進入循環左節點一定存在,而後再判斷右節點是否存在, //不存在的話最小值確定是左節點,若是存在的話,只有當右節點的值小於左節點時纔會讓最小值時右節點的值 int min = left; int right = (index << 1) + 2; //只有右節點存在且小於左節點的值時才進入循環 if(right < size && array[right] < array[left]) { min = right; } //若是兩子節點中的最小值都大於他自己的值時,調整結束 if(array[min] >= array[index]) { break; } //交換指定節點和其子節點中最小值的節點 int tmp = array[index]; array[index] = array[min]; array[min] = tmp; //調整後下標是min的結點等待繼續調整 index = min; left = (index << 1) + 1; } }
//此處size是數組最後一個元素的下標 public void heapify(int[] array, int size) { for (int i = (size - 1) >> 1; i >= 0; i--) { new SiftDown().siftDown(array, size, i); } }
3.下述爲PriorityQueue在構建堆時的源碼:數組
//其中size表示的是數組中元素的個數,所以和上面構建代碼中的循環條件有所差異,可是本質表達的是一個意思 private void heapify() { for (int i = (size >>> 1) - 1; i >= 0; i--) siftDown(i, (E) queue[i]); }