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)