搞了個HeapSort類,有個類變量type肯定是大頂堆仍是小頂堆。算法
注意,用堆的時候處理的數組是0元素不用的!!數組
上代碼:this
package www.com.leetcode.specificProblem; /** * 數組的0元素不用 * @author 85060 * */ public class HeapSort { private int heapType;//0表示大頂堆,其餘都是小頂堆 public HeapSort(int heapType) { this.heapType = heapType; } public void heapSort(int[] num) { makeHeap(num); for(int i = num.length - 1; i >= 2; i--) {//這個i能夠理解成,要和堆頂元素交換的那個index,確定到2就結束了 shiftDown(num, 1, i); //堆頂和堆最後的元素交換 int temp = num[1]; num[1] = num[i]; num[i] = temp; } } /** * 這個方法把傳進來的數組變成堆 * @param num */ public void makeHeap(int[] num) { for(int i = (num.length - 1)/2; i >= 1; i--) {//從最後一個有孩子的結點開始,作篩選操做,直到根節點也就是1號元素(0號不用) shiftDown(num, i, num.length - 1); } } /** * 將一顆樹從上到下篩選成堆的方法,前提這個根的兩個子樹都已是堆了 * @param heap * @param root 開始的結點,也就是根 * @param last 結束的結點,或者說是徹底二叉樹最後的那個結點 */ public void shiftDown(int[] heap, int root, int last) { int rootIndexTemp = root; int leftIndexTemp, rightIndexTemp, priorChildIndexTemp; while(2 * rootIndexTemp <= last) {//保證temp表示的樹的左孩子在範圍以內 leftIndexTemp = 2 * rootIndexTemp; rightIndexTemp = 2 * rootIndexTemp + 1; if(rightIndexTemp > last)priorChildIndexTemp = leftIndexTemp;//沒有右孩子,那麼孩子之間的優先者就直接左孩子 else priorChildIndexTemp = prior(heap[leftIndexTemp], heap[rightIndexTemp]) ? leftIndexTemp : rightIndexTemp; if(prior(heap[rootIndexTemp], heap[priorChildIndexTemp])) return;//比孩子結點優先,篩選結束 else { //交換操做 int temp = heap[rootIndexTemp]; heap[rootIndexTemp] = heap[priorChildIndexTemp]; heap[priorChildIndexTemp] = temp; rootIndexTemp = priorChildIndexTemp;//指針向下走,直到指定的last範圍內的葉節點爲止 } } } /** * 看是大頂堆仍是小頂堆,決定是大於優先仍是小於優先 * @param a * @param b * @return */ private boolean prior(int a, int b) { if(heapType == 0)return a >= b; else return a <= b; } public static void main(String[] args) { int[] a = {0,3,6,1,8,12,55};//注意0號元素不用 HeapSort heapSort = new HeapSort(0);//大頂堆,按正序排列 heapSort.heapSort(a); show(a); } public static void show(int[] array) { for(int i= 1; i < array.length; i ++) { System.out.print(array[i] + "\t"); } System.out.println(); } /** * 插入後調整堆的算法 * @param heap * @param newEleIndex 新元素的序號 */ public void adjustHeapAfterInsert(int[] heap, int newEleIndex) { int indexTemp = newEleIndex; while(indexTemp > 1 && prior(heap[indexTemp], heap[indexTemp / 2])) {//還沒到根節點&&比雙親結點的優先級大——就要交換和指針上移 int temp = heap[indexTemp]; heap[indexTemp] = heap[indexTemp / 2]; heap[indexTemp / 2] = temp; indexTemp = indexTemp / 2; } } }