首页 > 代码库 > 堆排序

堆排序

1、堆的特点
  • 是完全二叉树:除了树的最后一层结点不需要是满的,其他的每一层从左到右都完全是满的。
  • 通常采用数组实现
  • 堆中的每一个结点都满足堆的条件,也就是说每一个结点的关键字都大于等于(或小于等于)这个结点的子节点的关键字
技术分享
堆节点的访问:
     对于给定的某个结点的下标 i,
  • 它的父节点的下标为floor((i-1) / 2)
  • 它的左子节点的下标为2 * i + 1
  • 它的右子节点的下标为2 * i + 2

 

堆排序算法思想

将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根节点。将其与堆数组的末尾元素交换,此时末尾元素就是最大值,然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次最大值。如此反复执行,就能得到一个有序序列了。

/** * 时间复杂度O(NLogN), 空间复杂度O(1) * @author Wu * */public class HeapSort {        private static int[] arr = new int[]{1,0};    public static void main(String[] args) {        // 堆排        heapSort(arr);        // 打印排序后的数组        print(arr);    }        private static void heapSort(int[] arr) {                // 将待排序的序列构建成最大堆,从最后一个父节点开始        for(int i = arr.length / 2 - 1; i >= 0; i--) {            buildMaxHeapify(arr, i, arr.length);        }                // 逐步将每个最大值的根节点与末尾元素交换,并且再调整二叉树,使其成为大顶堆         for(int i = arr.length - 1; i >= 0; i--) {                        // 将堆顶记录和当前未经排序子序列的最后一个记录交换              int tmp = arr[0];              arr[0] = arr[i];              arr[i] = tmp;                       buildMaxHeapify(arr, 0, i); // 交换之后,需要重新检查堆是否符合大顶堆,不符合则要调整          }                            }    /**     * 构建最大堆过程     * @param arr    原数组     * @param i    根节点序号     * @param length    数组长度     */    private static void buildMaxHeapify(int[] arr, int i, int length) {        int largerChild;        int top = arr[i];        while(i < length / 2) {            // 只要i不在堆的最底层,也就是它只要至少还有一个子节点,就一直循环            int leftChild = 2 * i + 1;            int rightChild = 2 * i + 2;                        // 找最大的子节(要考虑右子节点不存在的情况)            if(rightChild < length && arr[rightChild] > arr[leftChild]) {                largerChild = rightChild;            } else {                largerChild = leftChild;            }                        // 交换根节点与子节点,使满足最大堆                        if(top >= arr[largerChild]) {                break;            }                        arr[i] = arr[largerChild];            i = largerChild;        }        arr[i] = top;      }            private static void print(int[] arr) {        for(int i = 0; i < arr.length; i++) {            System.out.print(arr[i] + " ");        }            }            }

 

堆排序