package junior.DAY_01;
public class Code_01_Sort
{
public static void main(String[] args)
{
//初始化數組
int len = (int)(Math.random()*20);//隨機生成20以內的數組長度
int[] arr = new int[len];
for(int i = 0; i < len; i++)//在數組內隨機生成1000內的值
{
arr[i] = (int)(Math.random()*1000) ;
}
for(int i = 0; i < len; i++)//格式化輸出數組
System.out.printf("%02d:%-4d\n",i,arr[i]);
heapSort(arr);
for(int i = 0; i < len; i++)//格式化輸出數組
System.out.printf("%02d:%-+4d\n",i,arr[i]);
}
public static void heapSort(int[] arr)
{//概念
//完全二叉樹:滿二叉樹或者滿二叉樹的過程樹
//用數組表示完全二叉樹:
//索引i的左節點索引爲:i*2+1 i*2+2 如果越界,則表示無該節點
//索引i的父節點索引爲:(i-1)/2
//大根堆:整棵樹的最大值就是根節點,每顆子樹的最大值就是該子樹的頭結點
//將數組調成最大堆的方式:數組中的每個元素都與父節點比較,如果比父節點大,則和父節點交換位置,
//交換位置後還 應繼續與父節點比較,直至小於父節點爲止
//將最大堆調成有序:將根節點與最後一個節點交換,這樣就把最大值換到了最後,並保持最大值的位置不變
//將堆的範圍-1(不理會最大值)。
//然後將根節點與較大的左右孩子節點作比較,如果孩子節點比較大,則交換位置;
//交換位置後繼續與孩子節點比較,直至比孩子節點大
//循環上面的步驟
if(arr == null || arr.length < 2)
return;
for(int i = 0; i < arr.length; i++)//將數組調成最大堆
heapInsert(arr,i);
int heapSize = arr.length;
int tmp = arr[0];//將最大堆的根節點和未排序堆的最後一個節點交換位置
arr[0] = arr[heapSize-1];
arr[heapSize-1] = tmp;
heapSize--;//將堆最後一個節點劃入已排序部分
while(heapSize > 0)//只要未排序部分還有元素,則繼續循環
{
heapify(arr,0,heapSize);//重新將未排序部分調整成最大堆
tmp = arr[0];//將最大堆的根節點和未排序堆的最後一個節點交換位置
arr[0] = arr[heapSize-1];
arr[heapSize-1] = tmp;
heapSize--;//將堆最後一個節點劃入已排序部分
}
}
public static void heapInsert(int[] arr, int index)
{//將數組調成最大堆的方式:數組中的每個元素都與父節點比較,如果比父節點大,則和父節點交換位置,
//交換位置後還 應繼續與父節點比較,直至小於父節點爲止
//往上走
while(arr[index] > arr[(index-1)/2])
{
int tmp = arr[index];
arr[index] = arr[(index-1)/2];
arr[(index-1)/2] = tmp;
index = (index-1)/2;
}
}
public static void heapify(int[] arr, int index, int size)
{//將未排序部分調成最大堆 index表示開始調整位置 size表示堆的大小
//往下走
int left = index*2 + 1;
while(left < size)//保證左孩子節點不越界
{
int largest = 0;//
if(left+1 < size)//找出左右孩子節點比較大的節點
{
if(arr[left] > arr[left+1])
largest = left;
else
largest = left+1;
}
else
largest = left;
if(arr[largest] < arr[index])//把較大的孩子節點與父節點比較
{//如果沒能比父節點大,則停止
largest = index;
break;
}
else//如果較大的孩子節點比父節點大,則與父節點交換位置
{
int tmp = arr[largest];
arr[largest] = arr[index];
arr[index] = tmp;
index = largest;//交換之後再接着與孩子節點比較
left = index*2+1;
}
}
}
}
常見算法之排序(進階部分)_堆排序_04
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.