您的位置:首页 > 其它

排序算法之堆排序

2018-03-04 16:08 169 查看
package sort;

import java.util.Arrays;

public class HeapSort {

public static void main(String[] args) {
int[] a = {3,6,2,9,5,8,7,1,4};
heapSort(a);
System.out.println(Arrays.toString(a));
}

/*堆排序,可认为是一种优化的选择排序,可分为两步
第一步建堆,第二步执行n-1次deleteMax
注意堆排序使用的堆和标准二叉堆略有不同,一是使用最大堆而不是最小堆;二是数据从数组下标0开始(二叉堆从1开始)*/
public static void heapSort(int[] a){
//buildHeap
//a.length/2 - 1 是怎么得到的?在二叉堆中位置i的父节点是floor(i/2),因此在堆排序中是floor((i+1)/2)-1,
//把i=a.length-1带入即得。
for (int i = a.length/2 - 1; i>=0; i--)
percDown(a, i, a.length);

//deleteMax
for (int i = a.length -1; i>0; i--){
//注意下滤时堆在不断变小,即已经排好序的数虽然还在数组里但不属于堆的一部分
swap(a, 0, i);
percDown(a, 0, i);
}
}

//核心方法——下滤
//从位置i开始下滤,即“空穴”的位置。n是堆大小
private static void percDown(int[] a, int i, int n) {
//使用和插入排序相同的小技巧。不显式使用交换
int tmp = a[i];

while(leftChild(i) < n){
int child = leftChild(i);
//确定两个儿子中较大的那个
if (child != n-1 && a[child] < a[child+1])
child++;
if (tmp < a[child])
a[i] = a[child];
else
break;

i = child;
}
a[i] = tmp;

}

private static int leftChild(int i) {
return 2 * i + 1;
}

private static void swap(int[] a, int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序