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)