代码如下:
public class HeapSort { public static void heapSort(DataWrap[] data) { System.out.println("开始排序"); int length = data.length; //循环建堆 for(int i = 0;i < length-1; i++) { //建堆 buiilMaxdHeap(data , length-1-i); //交换堆订和最后一个元素 swap(data , 0, length-1-i); System.out.println(java.util.Arrays.toString(data)); } } //交换data数组中i和j两处索引的元素 private static void swap(DataWrap[] data, int i, int j) { DataWrap tmp = data[i]; data[i] = data[j]; data[j] = tmp; } //对data数组从0到lastindex建最大堆 private static void buiilMaxdHeap(DataWrap[] data, int lastindex) { //从lastindex处节点(最后一个节点)的父节点开始 for(int i = (lastindex -1)/2;i >= 0;i--) { //k保存当前正在判断的节点 int k = i; //如果当前k节点的子节点存在 while(k * 2+1 <= lastindex) { //k节点的左子节点的索引 int biggerIndex = 2*k+1; //如果biggerIndex小于lastindex,即biggerindex+1 if(biggerIndex < lastindex) { //如果右子节点的值较大 if(data[biggerIndex].compareTo(data[biggerIndex+1]) < 0) { //biggerIndex总是记录较大子节点的索引 biggerIndex++; } } //如果k节点的值小于较大字节点的值 if(data[k].compareTo(data[biggerIndex]) < 0) { //交换它们 swap(data, k, biggerIndex); //将biggerIndex赋给k,开始while循环的下一次的循环 k = biggerIndex; } else { break; } } } } public static void main(String[] args) { DataWrap [] data = { new DataWrap(21, ""), new DataWrap(30, ""), new DataWrap(49, ""), new DataWrap(30, ""), new DataWrap(21, ""), new DataWrap(16, ""), new DataWrap(9, "") }; System.out.println("排序之前: " + java.util.Arrays.toString(data)); heapSort(data); System.out.println("排序之后: " + java.util.Arrays.toString(data)); } }
说明:
上面堆排序的关键在于buildMaxHeap()方法。该方法用于对data数组从0到lastindex索引范围内的元素建大顶堆,这样就选择出数组索引从0到lastindex范围内的最大元素。采用循环不断重复上面过程即可完成堆排序。
对于堆排序算法而言,假设有n项数据,需要进行n-1次建堆,每次建堆本身耗时为log2n,则其时间效率为O(nlog2n)。堆排序的空间效率很高,它只需要一个附加的程序单元用于交换,其空间效率为O(1)。