堆排
实现内容:
1.普通堆排–借助一个新数组实现
2.原地排序实现堆排–在原数组基础上实现
普通堆排:
//HeapTest.java
package heap;
import java.util.Arrays;
import java.util.Comparator;
//基于数组的堆
public class HeapTest<E>{
//堆结构为完全二叉树,值要求为任意一个节点要大于自身的左右节点的值(最大堆)
//故需要提供比较器进行数值比较
private Comparator<E> comparator;
private int size;
private E[] elemetData;
//设置数组初始化的的默认值
private static final int DEFAULT_CAPTITY=10;
//通过构造方法初始化数组及传入外部比较器
public HeapTest(){
this(DEFAULT_CAPTITY,null);
}
public HeapTest(int initCaptity){
this(initCaptity,null);
}
public HeapTest(int initCaptity,Comparator<E> comparator){
elemetData= (E[]) new Object[initCaptity];
this.comparator=comparator;
}
//将任意一个数组变为最大堆的形式
public HeapTest(E[] arr){
elemetData= (E[]) new Object[arr.length];
for(int i=0;i<elemetData.length;i++)
elemetData[i]=arr[i];
//更新size
size=elemetData.length;
//此处是将任意一个数组初步建立为堆结构后,从最后一个非叶子节点处向根节点一次做下沉操作,
//原因是所有叶子节点单独来看均是一个堆,故叶子结点都是满足堆结构的,只有非叶子节点可能不满足,故此种方式可大大提高效率
for(int i=(arr.length-1-1)/2;i>=0;i--)
siftDown(i);
}
//获得当前堆元素个数
public int getSize(){
return size;
}
//判断当前堆是否为空
public boolean isEmpty(){
return size==0;
}
//比较方法
private int compare(E o1,E o2){
if(comparator==null)
return ((Comparable<E>)o1).compareTo(o2);
return comparator.compare(o1,o2);
}
//获得当前节点的左孩子下标
public int leftChildIndex