堆排序(Heap Sort)是指利用堆這種數據結構所設計的一種排序算法。堆是一個近似徹底二叉樹的結構,並同時知足堆積的性質:即子結點的鍵值或索引老是小於(或者大於)它的父節點。java
什麼是堆?
堆是一個樹形結構,其實堆的底層是一棵徹底二叉樹。而徹底二叉樹是一層一層按照進入的順序排成的。按照這個特性,咱們能夠用數組來按照徹底二叉樹實現堆。大頂堆與小頂堆
大頂堆原理:根結點(亦稱爲堆頂)的關鍵字是堆裏全部結點關鍵字中最大者,稱爲大頂堆。大頂堆要求根節點的關鍵字既大於或等於左子樹的關鍵字值,又大於或等於右子樹的關鍵字值。
小頂堆原理:根結點(亦稱爲堆頂)的關鍵字是堆裏全部結點關鍵字中最小者,稱爲小頂堆。小堆堆要求根節點的關鍵字既小於或等於左子樹的關鍵字值,又小於或等於右子樹的關鍵字值。算法
public class HeapSort { public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < 10; i++) { list.add((int) (Math.random() * 100)); } System.out.println("排序前的集合爲:"); System.out.println(Arrays.toString(list.toArray())); heapSort(list); System.out.println("排序後的集合爲:"); System.out.println(Arrays.toString(list.toArray())); } /** * 建立堆, * @param list 待排序列 */ private static void heapSort(List<Integer> list) { //建立堆 for (int i = (list.size() - 1) / 2; i >= 0; i--) { //從第一個非葉子結點從下至上,從右至左調整結構 adjustHeap(list, i, list.size()); } System.out.println("dadui的集合爲:"); System.out.println(Arrays.toString(list.toArray())); //調整堆結構+交換堆頂元素與末尾元素 for (int i = list.size() - 1; i > 0; i--) { //將堆頂元素與末尾元素進行交換 int temp = list.get(i); list.set(i, list.get(0)); list.set(0, temp); //從新對堆進行調整 adjustHeap(list, 0, i); } } /** * 調整堆 * @param list 待排序列 * @param parent 父節點 * @param length 待排序列尾元素索引 */ private static void adjustHeap(List<Integer> list, int parent, int length) { //將temp做爲父節點 int temp = list.get(parent); //左孩子 int lChild = 2 * parent + 1; while (lChild < length) { //右孩子 int rChild = lChild + 1; // 若是有右孩子結點,而且右孩子結點的值大於左孩子結點,則選取右孩子結點 if (rChild < length && list.get(lChild) < list.get(rChild)) { lChild++; } // 若是父結點的值已經大於孩子結點的值,則直接結束 if (temp >= list.get(lChild)) { break; } // 把孩子結點的值賦給父結點 list.set(parent, list.get(lChild)); //選取孩子結點的左孩子結點,繼續向下篩選 parent = lChild; lChild = 2 * lChild + 1; } list.set(parent, temp); } }