首先明确什麼是堆?
一個數組:
int[] unsort={12,24,35,40,50,66,70,56,55};
堆的表現形式(這是一個最小堆,根節點是最小的):

用數組來表示堆,i結點的父結點下标就為(i – 1) / 2。它的左右子結點下标分别為2 * i + 1和2 * i + 2。(這樣就是給數組建好堆了)
下面進入堆排序的核心步驟:堆節點的移動
這裡需要對unsort[3]=12進行調整
對unsort[3]的子節點unsort[7],unsort[8]進行比較,符合最小堆!
對unsort[1]=24進行調整
跟左子節點進行調整
對unsort[0]=40進行調整
比較左右子節點,12<35;
12<40進行調整,上移;
比較左右子節點,24<50;
24<40,上移;
55<56;55>40;至此調整結束,24所在索引位置替換成40;
最小堆的根節點值最小。
下面看代碼:
//從i節點開始調整, i節點的子節點為 2*i+1, 2*i+2
public static void MinHeapFixdown(int a[], int i, int n)
{
int j, temp;
temp = a[i]; //取出節點值,比較,替換
j = * i + ; //左子節點
while (j < n)
{
if (j + < n && a[j + ] < a[j]) //在左右子節點中找最小的
j++;
if (a[j] >= temp) //說明已經排好序
break;
a[i] = a[j]; //把較小的子結點往上移動,替換它的父結點
i = j;
j = * i + ; //繼續往下周遊比較
}
a[i] = temp; //調整結束
}
有了堆的調整操作,建立堆,進行堆排序:
/**
* 建立最小堆
* 對數組中的每個元素進行子節點調整,最小的向上移動
* @param a 數組
* @param n 數組長度
*/
static void MakeMinHeap(int a[], int n)
{
//n/2-1可以定位到最後一個數組元素了,子節點分别為n-2,n-1
for (int i = n / - ; i >= ; i--)
MinHeapFixdown(a, i, n);
}
public static void MinheapsortTodescendarray(int a[], int n)
{
for (int i = n ; i >= ; i--)
{
MakeMinHeap(a,i);//從根節點調整定位最小值,調整過後a[0]最小
swap(a,i-,);//交換值,此時a[0]最小,進行下沉;下次周遊進行調整不會調整a[i-1]
}
}
此時得到的數組是遞減的:
public static void main(String[] args) {
int[] unsort={,,,,,,,,};
MinheapsortTodescendarray(unsort, unsort.length);
for (int i = ; i < unsort.length; i++) {
System.out.print(" "+unsort[i]);
}
}
運作結果:
101 100 80 56 55 40 24 12 8