需要了解完全二叉樹的知識
package select.sort;
public class HeapSorter {
public void sort(Integer[] array, int from, int len) {
build_heap(array,from,len);
for(int i=0;i<len;i++)
{
//把最大的跟置換到最後面
swap(array,from,from+len-1-i);
System.out.print("排序後\t");
for (int j = 0; j < array.length; j++) {
System.out.print(array[j]+"\t");
}
System.out.println();
shift_down(array,from,len-1-i,0);//始終從根節點開始置換,最大的上升到根節點,小的下沉到葉子節點
System.out.print("排序後\t");
for (int j = 0; j < array.length; j++) {
System.out.print(array[j]+"\t");
}
System.out.println();
}
}
//轉換數組的兩項
private void swap(Integer[] array,int x,int y) {
Integer temp = array[x];
array[x]=array[y] ;
array[y]=temp;
}
private final void build_heap(Integer[] array, int from, int len) {
int pos=(len-1)/2;//從第一個非葉子節點開始
for(int i=pos;i>=0;i--)
{
shift_down(array,from,len,i);
System.out.print("排序後\t");
for (int j = 0; j < array.length; j++) {
System.out.print(array[j]+"\t");
}
System.out.println();
}
}
//把所有的非葉子節點同子節點比較 第pos個元素 選擇與子節點中最大的元素與該節點置換
private final void shift_down(Integer[] array,int from, int len, int pos){
//暫時保存該節點的值, 因爲這裏可能不只進行一次比較
Integer tmp=array[from+pos];
int index=pos*2+1;//得到當前pos節點的左節點
while(index<len)//還存在左節點
{
if(index+1<len&&array[from+index].compareTo(array[from+index+1])<0)//如果存在右節點 則比較
{
//如果右邊節點比左邊節點大
index+=1;
}
//因爲下面是單向賦值,所以這裏要用tmp進行比較
if(tmp.compareTo(array[from+index])<0){
//注意這裏是單向賦值,少了一次置換,當前值已經賦給tmp
array[from+pos]=array[from+index];
//進行了置換操作後,以置換的子節點爲起點 (如果存在子節點) 還要繼續進行該操作
pos=index;
index=pos*2+1;
}else{
break;
}
}
//最終全部置換完畢後 才把臨時變量賦給最後的節點
array[from+pos]=tmp;
}
// 打印數組
public void printArray(Integer[] a) {
System.out.println();
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] a = { 45, 26, 13, 27, 35, 10, -455, -90, 2008, 1024, 101,
555, 216, 82,57 };
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+"\t");
}
System.out.println();
HeapSorter aa = new HeapSorter();
aa.sort(a, 0, a.length);
aa.printArray(a);
}
}