树之旅----创建堆和堆排序

   static int n;
    static int h[] = {3, 5, 6, 7, 9, 4, 2, 18, 2, 3, 56, 0, 5, 67, 65};

    public static void main(String[] args) {
        final int num = 14;
        int i;
        n = num;
        create();
        for (i = 1; i <= num; i++) {
            System.out.print(deleteMax() + ",");
        }

    }

    private static void create() {
        for (int i = n / 2; i >= 1; i--) {
            siftdown(i);
        }
    }

    private static void siftdown(int i) {
        int t, flag = 0;//作为是否需要继续向下调整的标志,0为需要,1为不需要
        while (flag == 0 && i * 2 <= n) {
            //先判断左节点
            if (h[i] > h[i * 2])
                t = i * 2;
            else
                t = i;
            //判断右节点
            if (i * 2 + 1 <= n)
                if (h[t] > h[i * 2 + 1])
                    t = i * 2 + 1;
            if (t != i) {
                swap(t, i);
                i = t;
            } else
                flag = 1;
        }
    }

    /**
     * 交换两个值
     *
     * @param x
     * @param i
     */
    private static void swap(int x, int i) {
        int t;
        t = h[x];
        h[x] = h[i];
        h[i] = t;
    }

    /**
     * 删除最大值
     *
     * @return
     */
    private static int deleteMax() {
        int t;//记录堆顶
        t = h[1];
        h[1] = h[n];
        n--;
        siftdown(1);
        return t;
    }

  实现思路:

1.准备一个一维数组h存放数组和一个变量记录n堆的个数

2.创建堆。只分析前一半的节点,因为后面的节点都是这些节点的子节点。然后从第一个节点开始。找到其左右节点。比较大小。需要改变顺序的就改变。

3.堆排序。每次都取出堆顶点,存入一个数组。改变堆的现有数量并进行调整,使该二叉树依旧是最小堆。每次都取出堆顶点,直到取完。

创建堆的时间复杂度是O(n)。

堆排序的时间复杂度和快速排序一样。O(NlogN)

没有虚过一天,真好
原文地址:https://www.cnblogs.com/dailinfu/p/7419722.html