排序算法——选择排序——堆排序


发布于 2016-07-23 / 27 阅读 / 0 评论 /
堆排是最优的选择排序算法

堆排序利用了优先级队列——二叉堆——的有序性。

1.堆排序算法

用优先级队列排序N个元素的过程有两个步骤:

(1)将每个元素enQueue到一个二叉堆,构建一个优先级队列。

(2)将优先级队列执行N次deQueue操作,将这些元素按出队顺序进行排列即可。

2.堆排序时间复杂度

优先级队列的deQueue时间复杂度为O(logN)。

优先级队列的enQueue时间复杂度也是O(logN)。

对于N个元素的enQueue和deQueue,时间复杂度为O(NlogN)。

相对直接选择排序来说,时间复杂度上有一定的优化。

3.堆排序代码实现

代码如下所示:

    public void heapSort(T[] a, int size) {
        int i;
        T tmp;

        // 入堆
        for (i = size / 2 - 1; i >= 0; i--) {
            percolateDown(a, i, size);
        }

        // 出堆
        for (i = size - 1; i >= 0; --i) {
            tmp = a[0];
            a[0] = a[i];
            a[i] = tmp;

            percolateDown(a, 0, i);
        }
    }

    public void percolateDown(T[] a, int hole, int size) {
        int child;
        T tmp = a[hole];
        while (hole * 2 + 1 < size) {
            child = hole * 2 + 1;
            if (child != size - 1 && a[child + 1] > a[child]) {
                child++;
            }
            if (a[child] > tmp) {
                a[hole] = a[child];
            } else {
                break;
            }
            hole = child;
        }
        a[hole] = tmp;
    }

4.堆排序适合场景

堆排序适合待排元素较多的场景。能保证最坏情况下时间复杂度为O(NlogN)。空间复杂度为O(1)

但是,堆排序为不稳定的排序。