堆排序是对数组进行排序的一个方法,其用到的思想是能够经过构建一个树直观的来看,但它自己的存储结构与树确实是一毛钱关系都没有。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