堆數據結構是一種數組對象,它能夠被視爲一顆徹底二叉樹。堆的訪問能夠經過三個函數來進行即,java
parent(i) return floor(i/2); left(i) return 2i; right(i) return 2i + 1;
left操做能夠經過一步左移操做完成,right操做能夠經過左移並在地位+1實現,parent操做則能夠經過把i右移一位獲得。在實現中一般會使用宏或者內聯函數來實現這三個操做。算法
二叉堆有兩種,最大堆和最小堆。對於最大堆有api
A[i] >= A[left(i)] && A[i] >= A[right(i)]
最小堆則是數組
A[i] <= A[left(i)] && A[i]<= A[right(i)]
最堆排序算法中,使用的是最大堆,最小堆一般在構造優先隊列時使用。堆能夠被當作是一棵樹,結點在堆中的高度定義爲從本結點到葉子的最長簡單降低路徑上邊的數目;定義堆的高度爲樹根的高度。數據結構
下面就關於堆的幾個基本函數作一下說明:函數
maxHeapify(),運行時間爲O(lgn)用於保持堆的性質;測試
bulidMaxHeap(),以線性時間運行,能夠在無序的輸入數組基礎上構造出最大堆;ui
heapSort(),運行時間爲O(nlgn),對一個數組原地進行排序。this
maxHeapify(A,i) l <- left(i) r <- right(i) if l <= heap-size[A] and A[l] > A[i] then largest <- l else largest <- i if r <= heap-size[A] and A[r] > A[largest] then largest <- r if largest != i then exchange A[i] <-> A[largest] // 交換i和比它大的那個子結點 maxHeapify(A,largest); // 遞歸調用
buildMaxHeap(A) heap-size[A] <- length[A] for i <- floor(length[A] / 2) downto 1 do max-heapify(A,i)
heapSort(A) buildMaxHeap(A) for i <- length[A] downto 2 do exchange A[1] <-> A[i] heap-size[A] <- heap-size[A] - 1 maxHeapify(A,1)
import java.io.Serializable; /** * Date: 2014/8/17 * Time: 16:02 */ public class Heap implements Serializable{ private int heapLength; private int [] data; public int getHeapLength() { return heapLength; } public void setHeapLength(int heapLength) { this.heapLength = heapLength; } public int[] getData() { return data; } public void setData(int[] data) { this.data = data; } }
/** * Created with IntelliJ IDEA. * Date: 2014/8/17 * Time: 15:39 */ public class HeapSort { public final static int getLeft(int i) { return i << 1; } public final static int getRight(int i) { return (i << 1) + 1; } public final static int getParent(int i) { return i >> 1; } /** * 保持堆的性質 * * @param heap * @param i */ public static void maxHeapify(Heap heap, int i) { if (null == heap || null == heap.getData() || heap.getData().length <= 0 || i < 0) return; int l = getLeft(i); int r = getRight(i); int largest = 0; if (l < heap.getHeapLength() && heap.getData()[l] > heap.getData()[i]) largest = l; else largest = i; if (r < heap.getHeapLength() && heap.getData()[r] > heap.getData()[largest]) largest = r; if (largest != i) { int tmp = heap.getData()[i]; heap.getData()[i] = heap.getData()[largest]; heap.getData()[largest] = tmp; maxHeapify(heap, largest); } } /** * 創建最大堆 * * @param array * @return */ public static Heap bulidMaxHeap(int[] array) { if (null == array || array.length <= 0) return null; Heap heap = new Heap(); heap.setData(array); heap.setHeapLength(array.length); for (int i = (array.length >> 1); i >= 0; i--) maxHeapify(heap, i); return heap; } /** * 堆排序 * * @param array */ public static void heapSort(int[] array) { if (null == array || array.length <= 0) return; Heap heap = bulidMaxHeap(array); if (null == heap) return; for (int i = heap.getHeapLength() - 1; i > 0; i--) { int tmp = heap.getData()[0]; heap.getData()[0] = heap.getData()[i]; heap.getData()[i] = tmp; heap.setHeapLength(heap.getHeapLength() - 1); maxHeapify(heap, 0); } } }
public class Main { public static void main(String[] args) { int a[] = {9, 3, 4, 1, 5, 10, 7}; System.out.println("Hello World!"); Sort sort = new Sort(); // sort.bubbleSort(a); // sort.selectSort(a); // sort.insertionSort(a); HeapSort.heapSort(a); for (int i = 0; i < a.length; i++) System.out.println(a[i]); } }