
待排序的数据:27, 15, 19, 18, 28, 34, 65, 49, 25, 37
因为堆实际上是在二叉树的基础上做的一些调整。
在操作堆的时候本质是利用了二叉树的思想。
给每一个数据一个下标值。

下图是排列好的二叉树。

但是它此时既不是大根堆也不是小根堆,即不是一个堆。
要将它变成一个堆,要先将它变成大根堆或者小根堆。
如果是要建立成大根堆,先将它的子树全部建成大根堆。此时,这棵树整体也就变成了一个大根堆。

先将图中画红圈的建成大根堆,建成后,整棵树就是一个大根堆了。
有两个方法:
实现向下调整
最后一棵子树建堆后:

图中的4下标和9下标的结点进行了交换。
第1步:

第2步:

下图的3下标和7下标交换了。

第3步:

第4步:

第5步:

第6步:

走到这里就会发现,3下标位置的根节点又不是大根堆了。
要让 r 重新指向3下标,i 再指向左右孩子最大值。
第7步:

第8步:

程序并不知道这一步交换完成后,15有没有左右节点了。
因此并不能确定交换一次 r 和 i 结点之后就为大根堆了。
解决办法:

此时 i 的值大于数据个数(10)的最大下标值(9),此时说明15左右没有孩子。
此时如果 i 的值乘2加1大于9,就说明此时的 i 指向的就是最后一个结点了。
for (int parent = (array.length - 1 - 1) / 2; parent >= 0 ; parent--) {
}
shiftDown(array, parent, array.length);
public static void shiftDown(int[] array, int parent, int len) {
}
int child = (2 * parent) + 1;
while (child < len) {
if (child + 1 < len && array[child] < array[child + 1]) {
child++;
}
}

if (array[child] > array[parent]) {
}
if (array[child] > array[parent]) {
swap(array, child, parent);
parent = child;
child = 2 * parent + 1;
}
public static void swap(int[] array, int i, int j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
最终实现的大根堆:

creatBigHeap(array);
int end = array.length - 1;
while (end > 0) {
swap(array, 0, end);
shiftDown(array, 0, end);
end--;
}
交换一次后

此时不为大根堆了,先建成大根堆,再交换。

65 是排序好的了,所以在重新建成大根堆的时候不需要处理65,交换第2次。

按照上面的步骤会逐渐排成:

public static void heapSort(int[] array) {
creatBigHeap(array);
int end = array.length - 1;
while (end > 0) {
swap(array, 0, end);
shiftDown(array, 0, end);
end--;
}
}
//建堆
public static void creatBigHeap(int[] array) {
for (int parent = (array.length - 1 - 1) / 2; parent >= 0 ; parent--) {
//调用向下调整
shiftDown(array, parent, array.length);
}
}
//向下调整的方法
public static void shiftDown(int[] array, int parent, int len) {
int child = (2 * parent) + 1;
while (child < len) {
if (child + 1 < len && array[child] < array[child + 1]) {
child++;
}
if (array[child] > array[parent]) {
swap(array, child, parent);
parent = child;
child = 2 * parent + 1;
}else {
break;
}
}
}
//交换的方法
public static void swap(int[] array, int i, int j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
