堆排序

一、定义

堆排序(Heap Sort)是一种基于优先队列(堆实现)的排序方式。
堆排序的步骤如下:

  1. 初始时待排序元素保存在数组形式的二叉树中:


    堆排序_第1张图片
  2. 排序时,从树的最右子结点的父结点(上图的5-E)开始下沉,以提高性能,直到根结点为止:

for (int k = n/2; k >= 1; k--)
    sink(pq, k, n);

此时根结点就是最大元素(假设大顶堆)


堆排序_第2张图片
  1. 接着重复以下循环:
    将根结点与最右下子结点交换,然后再对根结点下沉,共进行N次。


    堆排序_第3张图片

二、实现

public class HeapSort {
    // This class should not be instantiated.
    private HeapSort() { }

    public static void sort(Comparable[] pq) {
        int n = pq.length;
        for (int k = n/2; k >= 1; k--)
            sink(pq, k, n);
        while (n > 1) {
            exch(pq, 1, n--);
            sink(pq, 1, n);
        }
    }

   /***************************************************************************
    * Helper functions to restore the heap invariant.
    ***************************************************************************/
    private static void sink(Comparable[] pq, int k, int n) {
        while (2*k <= n) {
            int j = 2*k;
            if (j < n && less(pq, j, j+1)) j++;
            if (!less(pq, k, j)) break;
            exch(pq, k, j);
            k = j;
        }
    }

   /***************************************************************************
    * Helper functions for comparisons and swaps.
    * Indices are "off-by-one" to support 1-based indexing.
    ***************************************************************************/
    private static boolean less(Comparable[] pq, int i, int j) {
        return pq[i-1].compareTo(pq[j-1]) < 0;
    }

    private static void exch(Object[] pq, int i, int j) {
        Object swap = pq[i-1];
        pq[i-1] = pq[j-1];
        pq[j-1] = swap;
    }

    // print array to standard output
    private static void show(Comparable[] a) {
        for (int i = 0; i < a.length; i++) {
            StdOut.println(a[i]);
        }
    }
}

三、性能分析

  • 时间复杂度
    O(NlgN)
  • 空间复杂度
    O(N)

你可能感兴趣的:(堆排序)