Java实现的堆排序算法
堆排序算法是对序列进行排序的众多算法之一。
堆排序算法的时间复杂度为O(nlgn),并且具有空间原址性:任何时候都只需要常数个额外的元素空间存储临时数据。
算法中涉及的基本概念:
1、二叉堆:一个近似的完全二叉树,树上的每一个节点对应数组中的一个元素。对应的规则为数组从左到右,二叉堆从上到下,同层从左到右。
2、最大堆:堆中的某个节点至多与父节点一样大的二叉堆。
算法的基本操作过程:
1、将数组构造成一个二叉堆(Heap),直接将一个数组看成一个二叉堆,其中一个节点i也是数组中的第i个元素。
2、维护最大堆(MaxHeapify):该过程中,根节点的子节点都是一个最大堆,只有根节点不满足最大堆的性质,通过将根节点与子节点比较下沉,将最大的子节点上浮为根节点,将该根节点下浮至适当的位置从而完成对一个最大堆的维护。
3、构造最大堆(BuilMaxHeap):对于一个叶子节点来说,这个节点一定是一个最大堆。那么将该节点的父节点和兄弟节点包括进来的就可以应用维护最大堆过程将新的子堆构成一个最大堆,通过反复调用这个过程从而将整个堆构建成一个最大堆。
4、排序(HeapSort):首先将一个堆构建成一个最大堆,这个最大堆的根节点一定是这个数组中的最大值,也同时对应着此时数组中的第0个元素。通过将第0个元素与最后一个元素交换并将堆的大小减1将该值从堆中剔除就得到了元素中的最大值并且排列在了数组的最后。对于新的堆通过维护最大堆过程调整成新的最大堆然后继续剔除根节点就得到数组中的第二大的元素并排列到数组的倒数第二位,反复这个过程就完成了数组的排序。
对于过程可能描述不太清楚,请参照相关资料。以下是用Java实现的该排序算法,为了保证该排序算法的通用型,使用了泛型。
代码块
package myjava.algorithms;
import java.util.Arrays;
/**
*
* 堆排序的泛型实现
*/
public class GenericsHeapSort<T extends Comparable<T>> {
private T[] a;
private int len;
private boolean isMaxHeap = false;
public GenericsHeapSort(T[] a){
this.a = a;
len = a.length;
}
//获得该节点的左子节点
private int left(int i){
return 2*i+1;
}
//获得该节点的右子节点
private int right(int i){
return 2*i+2;
}
//获得该节点的父节点
private int parent(int i){
return (int) (i/2==0?(i/2-1):(i/2));
}
//最大堆维护
public void maxHeapify(int i, int heapsize){
System.out.println("MaxHeapify.......");
int l = left(i);
int r = right(i);
int largest = i;
T temp;
if(l<=heapsize-1 && (a[l].compareTo(a[i]))>0)
largest = l;
if(r<=heapsize-1 && (a[r].compareTo(a[largest]))>0)
largest = r;
if(largest != i){
temp = a[i];
a[i] = a[largest];
a[largest] = temp;
System.out.println("Largest "+largest);
System.out.println("...."+Arrays.toString(a));
maxHeapify(largest,heapsize);
}
}
public void maxHeapify(int i){
maxHeapify(i,len);
}
//构建最大堆
public void buildMaxHeap(){
for(int i=len/2;i>=0;i--)
maxHeapify(i);
isMaxHeap = true;
}
//排序
public void heapSort(){
if(!isMaxHeap)
buildMaxHeap();
T temp;
int heapsize = len;
for(int i=len -1;i>=1;i--){
temp = a[0];
a[0] = a[i];
a[i] = temp;
heapsize = heapsize -1;
maxHeapify(0,heapsize);
}
}
public static void main(String[] args){
Integer[] a = {4,1,3,2,16,9,10,14,8,7};
GenericsHeapSort hs = new GenericsHeapSort(a);
hs.heapSort();
System.out.println("Result....."+Arrays.toString(a));
}
}