堆排序是對數組進行排序的一個方法,其用到的思想是能夠經過構建一個樹直觀的來看,但它自己的存儲結構與樹確實是一毛錢關係都沒有。java
堆排序是仿照樹的作法,把整個數組抽象成一棵徹底二叉樹。數組第一個元素就是這個徹底二叉樹的根結點。徹底二叉樹的概念能夠在百度上自行普及下。數組
堆排序從大的層面,有三個步驟:ui
(1)找出一個備用的數組spa
(2)把備用的數組調整成一個堆(最大堆或最小堆)code
(3)每次把第一個元素與最後一個元素互換,而後把最後一個元素踢出數組,再把剩下元素組成的數組調整成一個堆排序
/** * @date 2017/11/16 上午10:22 */ public class HeapSort { public static void main(String args[]) { int[] a = { 1, 3, 9, 2, 5, 29, 2, 4, 8 }; print(a); buildHeap(a); print(a); heapSort(a); print(a); } /** * 堆排序的具體實現 */ private static void heapSort(int[] a) { int size = a.length; for (int i = size - 1; i >= 0; i--) { swap(a, 0, i); heapAdjust(a, 0, i); } } //從下向上進行堆的構建 private static void buildHeap(int[] a) { int size = a.length; for (int i = size / 2 - 1; i >= 0; i--) { heapAdjust(a, i, size); } } //從一個節點從上向下進行堆的調整 private static void heapAdjust(int[] a, int index, int size) { int lchild = index * 2 + 1; int rchild = index * 2 + 2; int maxIndex = index; if ((lchild < size) && (a[lchild] > a[index])) { maxIndex = lchild; } if ((rchild < size) && (a[rchild] > a[maxIndex])) { maxIndex = rchild; } if (maxIndex != index) { swap(a, maxIndex, index); heapAdjust(a, maxIndex, size); } } //交換數組中兩個下標元素的值 private static void swap(int[] a, int x, int y) { int temp = a[x]; a[x] = a[y]; a[y] = temp; } //對數組進行打印 private static void print(int[] a) { for (int i = 0; i < a.length; i++) { System.out.print(a[i] + ","); } System.out.println(); } }
代碼的核心其實就是heapAdjust()方法,這個方法的做用是:get
在當前結點爲根結點的樹是一個堆的狀況下,改變根結點的值,這個方法會把以這個結點爲根結點的二叉樹調整成一個堆。class
在進行堆構建的時候,其實也是進行了一個簡單的迭代。先從下向上一個結點一個結點的保證堆的性質,直至根結點。百度
而在排序的時候,每次把根結點取出放到最後,那最後一個元素放的就必定是這個二叉樹中的最大或最小元素。交換元素值以後再進行堆的調整,調整到最後,排序就完成了。date