將整個數組看做一個二叉樹heap, 下標0爲堆頂層, 下標1, 2爲次頂層, 而後每層就是"3,4,5,6", "7, 8, 9, 10, 11, 12, 13, 14", ..., 對於其中的每個非葉子節點, 其子節點的下標爲 2 * pos + 1 和 2 * pos + 2java
循環進行如下工做:數組
將堆初始化爲大頂堆的處理this
public class DemoHeapSort { // 待排序的數組 private int[] ints; // 當前堆的右邊界(下標) private int limit; public DemoHeapSort(int ... ints) { this.ints = ints; this.limit = ints.length - 1; } public void sortAll() { while (limit > 0) { resort(); swap(0, limit); limit--; } } public void resort() { // 起點pos爲當前堆length / 2 - 1 for (int i = (limit + 1) / 2 - 1; i >= 0; i--) { int pos = i; while (true) { pos = check(pos); if (pos == 0) { break; } } } } /** * 檢查pos位置, 自上而下判斷是否都知足大頂堆的要求 * 其左右子節點的下標爲 2*pos+1 和 2*pos+2 * * @param pos 當前要檢查的下標 * @return 若是無調整, 則返回0, 若是有調整, 則返回被調整的子節點下標 */ private int check(int pos) { int posLeft = 2 * pos + 1; int posRight = 2 * pos + 2; if (posLeft > limit) { // 沒有子節點 return 0; } if (posRight > limit) { // 僅有左節點 if (ints[pos] < ints[posLeft]) { swap(pos, posLeft); return posLeft; } else { return 0; } } // 左右節點都有 if (ints[posLeft] > ints[posRight]) { if (ints[pos] < ints[posLeft]) { swap(pos, posLeft); return posLeft; } else { return 0; } } else { if (ints[pos] < ints[posRight]) { swap(pos, posRight); return posRight; } else { return 0; } } } public void print() { for (int a : ints) { System.out.printf("%3d", a); } System.out.print("\n"); } private void swap(int a, int b) { int tmp = ints[a]; ints[a] = ints[b]; ints[b] = tmp; } public static void main(String[] args) { DemoHeapSort hs = new DemoHeapSort(10, 97, 9, 1,63, 64, 8, 17, 33, 7, 21, 0, 7, 75, 13, 18, 2, 99, 87); hs.sortAll(); hs.print(); } }
.3d