//堆有三個操作。維護堆,建堆,堆排序。
public class heapsort {
// 維護最大堆
public static void maxheap(int nums[], int i,int size) {
// 左孩子節點
int l = 2*i+1;
// 右孩子節點
int r = 2*i+2;
// 最大數節點
int largest;
// 如果左孩子節點在隊列範圍並且大於父節點
if(l<=size-1 &&nums[l]>nums[i]){
largest = l;
}else {
// 可能是沒有子節點或者是父節點大於子節點
largest = i;
}
// 右節點存在並且右節點大於左節點(父節點)
if (r<=size-1 && nums[r]>nums[largest]){
largest = r;
}
// 最大節點不是父節點
if (largest!=i){
int temp = nums[i];
nums[i] = nums[largest];
nums[largest] = temp;
// 交換值後,以下標爲largest節點的子節點可能違反最大堆特性所以要遞歸調用
maxheap(nums,largest,size);
}
}
// 建立堆
public static void buildheap(int nums[]) {
// 一個二叉樹葉節點只有一半
for (int i =nums.length/2-1;i>=0;i--){
maxheap(nums,i,nums.length);
}
}
// 因爲是個最大堆,依次減去剩下最大堆的頭結點來進行排序。
public static void sortheap(int nums[]){
// 先建好最大堆
buildheap(nums);
// 堆的長度
int j = nums.length;
// 把根節點和最後一個葉節點交換,並且更新數組長度。
while(j>1){
int temp = nums[0];
nums[0] = nums[j-1];
nums[j-1] = temp;
j--;
maxheap(nums,0,j);
}
}
public static void main(String[] args) {
int a[] ={4,1,3,2,16,9,10,14,8,7};
sortheap(a);
for (int b:a){
System.out.print(b+",");
}
}
}