主程序:
辅助类方法
package yangkunlin.algorithm.sort;
import yangkunlin.algorithm.tool.SortTool;
/**
* 堆排序
*
* 前提:堆的根节点的序号是1,并且满足最大堆属性。
* 堆是存放在数组中的,堆的大小要小于数组的大小。
* 注意下边个方法的参数是以1开始记得。
*
* 时间复杂度:O(nlgn)
* 原地排序,不需要多余的空间。
* @author yangkunlin
*
*/
public class HeapSort {
/**
* 最大堆排序算法,将source按最大堆排序算法由小到大排序
* @param source
*/
public void heapSort(int[] source){
bulidMaxHeap(source);
for (int lastElement = source.length -1; lastElement >0; lastElement--) {
SortTool.exchange(source, 0, lastElement);
maxHeapily(source, 1, lastElement);
}
}
/**
* 以第i个元素为根的子树保持最大树,终点为第heapSize个元素。source中第heapSize个元素之后的元素不予理会。
* 即堆的大小为heapSize,从数组第一个元素到第heapSize个元素为止。
* @param source
* @param i 第i个元素,指的是从1开始的。因此后边在取数组元素的时候,都有-1.
* @param heapSize
*/
public void maxHeapily(int[] source,int i ,int heapSize){
int left = Left(i);
int right = Right(i);
int largest = i;
if(heapSize >= left && source[left-1] > source[i-1] ){
largest = left;
}
if(heapSize >= right && source[right-1] > source[largest-1]){
largest = right;
}
if(largest != i){
SortTool.exchange(source, i-1, largest-1);
maxHeapily(source, largest ,heapSize);
}
}
/**
* 构建最大堆树
* @param source
*/
public void bulidMaxHeap(int[] source){
//beginFlag以后的都是叶子节点。
int beginFlag = (int)Math.floor(source.length/2);
for(int i = beginFlag; i >= 1 ;i--){
maxHeapily(source, i , source.length);
}
}
/**
* 根据序号获得左儿子的序号
*/
public int Left(int i){
return 2*i;
}
/**
* 根据序号获得右儿子的序号
*/
public int Right(int i){
return 2*i + 1;
}
}
辅助类方法
/**
* 交换数组中两元素的位置
* @param source
* @param i
* @param j
*/
public static void exchange(int[] source, int i, int j) {
int bridge = source[i];
source[i] = source[j];
source[j] = bridge;
}