堆排序的基本思想是:html
将待排序序列构形成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。而后将剩余n-1个元素从新构形成一个堆,这样会获得n个元素的次小值。如此反复执行,便能获得一个有序序列了。java
算法过程:算法
步骤一 构造初始堆。将给定无序序列构形成一个大顶堆(通常升序采用大顶堆,降序采用小顶堆)。数组
步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。而后继续调整堆,再将堆顶元素与末尾元素交换,获得第二大元素。如此反复进行交换、重建、交换。code
/** * 堆排序(此方法最后获得的是升序的数组) * @param elements */ public static void heapSort(int[] elements) { int lastParentNodeIndex = 0; for(int tempLength = elements.length; tempLength > 1; tempLength--) { // 步骤1.构建大顶堆 lastParentNodeIndex = (tempLength >> 1) - 1; for(int i = lastParentNodeIndex; i >= 0; i--) { // 从第一个非叶子结点从下至上,从右至左调整结构 adjustHeap(elements, i, tempLength); } System.out.println("构建大顶堆:"+Arrays.toString(elements)); // 交换堆顶元素与末尾元素 swapElement(elements, 0, tempLength-1); System.out.println("交换堆顶元素与末尾元素:"+Arrays.toString(elements)); System.out.println("-----------------------------------------------------"); } } private static void adjustHeap(int[] elements, int parentNodeIndex, int length) { int leftNodeIndex = (parentNodeIndex << 1) + 1; int rightNodeIndex = leftNodeIndex + 1; if((length - 1) >= rightNodeIndex) { // parentNodeIndex指定的节点有左右两个子节点 // 先比较左右连个子节点的元素大小,取大的子节点与父节点比较,若子节点的元素大于父节点,则把这两个元素交换 if(elements[leftNodeIndex] >= elements[rightNodeIndex]) { if(elements[leftNodeIndex] > elements[parentNodeIndex]) { swapElement(elements,leftNodeIndex, parentNodeIndex); adjustHeap(elements, leftNodeIndex, length); } } else { if(elements[rightNodeIndex] > elements[parentNodeIndex]) { swapElement(elements, rightNodeIndex, parentNodeIndex); adjustHeap(elements, rightNodeIndex, length); } } } else if((length - 1) >= leftNodeIndex) { // parentNodeIndex指定的节点只有左边一个个子节点 // 直接比较左边子节点与父节点的大小,若子节点的元素大于父节点,则把这两个元素交换 if(elements[leftNodeIndex] > elements[parentNodeIndex]) { swapElement(elements,leftNodeIndex, parentNodeIndex); adjustHeap(elements, leftNodeIndex, length); } } else { // 元素下标超出了参数length-1,什么事都不用作 } } private static void swapElement(int[] elements, int i, int j) { int temp = elements[i]; elements[i] = elements[j]; elements[j] = temp; }
调用方法:htm
public static void main(String[] args) { int[] array = {82 ,31 ,29 ,71, 72, 42, 64, 5, 110}; heapSort(array); }
结果:blog
构建大顶堆:[110, 82, 64, 71, 72, 42, 29, 5, 31] 交换堆顶元素与末尾元素:[31, 82, 64, 71, 72, 42, 29, 5, 110] ----------------------------------------------------- 构建大顶堆:[82, 72, 64, 71, 31, 42, 29, 5, 110] 交换堆顶元素与末尾元素:[5, 72, 64, 71, 31, 42, 29, 82, 110] ----------------------------------------------------- 构建大顶堆:[72, 71, 64, 5, 31, 42, 29, 82, 110] 交换堆顶元素与末尾元素:[29, 71, 64, 5, 31, 42, 72, 82, 110] ----------------------------------------------------- 构建大顶堆:[71, 31, 64, 5, 29, 42, 72, 82, 110] 交换堆顶元素与末尾元素:[42, 31, 64, 5, 29, 71, 72, 82, 110] ----------------------------------------------------- 构建大顶堆:[64, 31, 42, 5, 29, 71, 72, 82, 110] 交换堆顶元素与末尾元素:[29, 31, 42, 5, 64, 71, 72, 82, 110] ----------------------------------------------------- 构建大顶堆:[42, 31, 29, 5, 64, 71, 72, 82, 110] 交换堆顶元素与末尾元素:[5, 31, 29, 42, 64, 71, 72, 82, 110] ----------------------------------------------------- 构建大顶堆:[31, 5, 29, 42, 64, 71, 72, 82, 110] 交换堆顶元素与末尾元素:[29, 5, 31, 42, 64, 71, 72, 82, 110] ----------------------------------------------------- 构建大顶堆:[29, 5, 31, 42, 64, 71, 72, 82, 110] 交换堆顶元素与末尾元素:[5, 29, 31, 42, 64, 71, 72, 82, 110] -----------------------------------------------------
参考文档:排序