低头要有勇气,抬头要有底气。
堆排序的增加理解:
由于前面对于堆排序有些疑问存在,因此今天我再一次研究了一下堆排序的算法和设计思想。
1.构建大根堆的算法设计
根据二叉树的性质我们可以得非叶节点最大序号值为size/2 。
因此我们根据一个数据构建大根堆的算法就是:
【1】首先将当前的数组作为一个完全二叉树保存
【2】从最后一个非叶节点进行构建大顶堆
【3】循环 -》 利用判定和递归进行构建大顶堆
2.堆排序的算法思路使用白话的方式来描述就是
1)构建一个大根堆;
2)将根节点0和最后一个结点n-1兑换;
3)交换后调整构建大根堆;
4)n=n-1;如果n!=0 重复执行 2)——3)
5)结束 说明排序完成 可以直接输出。
3. 堆排序的Demo程序实现(Java)
package ds.java.ch09;
/**
* @author LbZhang
* @version 创建时间:2015年11月21日 下午3:15:34
* @description 类说明
*/
public class MyHeapSort {
public static int[] Data = { 5, 4, 6, 3, 9, 7, 0, 1, 2, 8 };
public static void main(String[] args) {
printArray(Data);
heapSort(Data);
}
private static void heapSort(int[] data) {
// 第一步调整大根堆
int len = data.length;
for (int i = len / 2; i >= 0; i--) {
heapAdjust(i, data, len);
}
printArray(data);
for (int i = len-1; i >= 0; i--) {
int temp = data[i];
data[i] = data[0];
data[0] = temp;
heapAdjust(0, data, i);// 重新调整堆顶节点成为大顶堆
}
printArray(data);
}
private static void heapAdjust(int root, int[] data, int size) {
int left = 2 * root;
int right = 2 * root + 1;
int max = root;
if (root < size / 2) {
if (left < size && data[left] > data[max]) {
max = left;
}
if (right < size && data[right] > data[max]) {
max = right;
}
if (max != root) {
int temp = data[root];
data[root] = data[max];
data[max] = temp;
// 避免调整之后以max为父节点的子树不是堆
heapAdjust(max, data, size);
}
}
}
private static void printArray(int[] data) {
for (int i = 0; i < Data.length; i++) {
System.out.print(data[i] + " - ");
}
System.out.println();
}
}