堆排序
堆排序過程:(這裡選用大頂堆)
一個完整的堆排序需要經過反覆的兩個步驟:構造堆結構和堆排序輸出。
一、構造堆結構
1)將原始的資料,按層遍歷,依次放置到一個完全二叉樹的各個節點中;
2)對這個完全二叉樹進行編號,從根開始,按層遍歷,依次編號為1、2、3、,...,n;
3)從編號為┗n/2┛的結點開始,進行“左--根--右”的父子結點值比較。大數放在父結點,小數放在子結點。
4)接著,從編號為┗n/2┛-1的結點開始,也是“左--根--右”,父大子小。
5)直到編號為1的結點,繼續“左--根--右”,父大子小。
二、堆排序輸出
將大頂堆中的根結點與最後的葉子結點進行交換,然後對序列中的前n-1記錄進行篩選,重新把完全二叉樹調整為一個“大頂堆”,如此反覆,直到排序結束。
a)對於大根堆,我們採用的是從小到大輸出,因此將其放到陣列的末尾,如圖a,結點97與結點38交換,
b)將結點38換到根結點的位置後,要從新構造堆,即使它保持大根堆的結結構,此時結點97已不在堆中。如圖b
c)重複上述過程,取此時堆結構的根節點(最大值)進行交換,放在陣列後面,此時結點77與結點38交換。如圖c
d)然後重複將剩餘的資料構造堆結構,取根結點與最後一個結點交換,將得到圖d所示結果。
e)再進一步執行堆排序輸出,編號1與編號3互換,得到圖e結果。
,
f)對最後的兩個資料進行處理,得到最終結果。
程式碼如下:
package cn.whut.sort;
public class HeapSort2 {
static final int SIZE=10;
/**
* 堆排序
* @param a,陣列a
* @param n,個數為n
*/
static void heapSort(int a[],int n)
{
int i,j,h,k;
int t;
for(i=n/2-1;i>=0;i--) //將a[0,n-1]建成大根堆
{
while(2*i+1<n) //第i個結點有右子樹
{
j=2*i+1 ;
if((j+1)<n)
{
if(a[j]<a[j+1]) //右左子樹小於右子樹,則需要比較右子樹
j++; //序號增加1,指向右子樹
}
if(a[i]<a[j]) //比較i與j為序號的資料
{
t=a[i]; //交換資料
a[i]=a[j];
a[j]=t;
i=j ; //堆被破壞,需要重新調整
}
else //比較左右子結點均大則堆未破壞,不再需要調整
{
break;
}
}
}
//輸出構成的堆
System.out.print("原資料構成的堆:");
for(h=0;h<n;h++)
{
System.out.print(" "+a[h]); //輸出
}
System.out.print("\n");
for(i=n-1;i>0;i--)
{
t=a[0]; //與第i個記錄交換
a[0] =a[i];
a[i] =t;
k=0;
while(2*k+1<i) //第i個結點有右子樹
{
j=2*k+1 ;
if((j+1)<i)
{
if(a[j]<a[j+1]) //右左子樹小於右子樹,則需要比較右子樹
{
j++; //序號增加1,指向右子樹
}
}
if(a[k]<a[j]) //比較i與j為序號的資料
{
t=a[k]; //交換資料
a[k]=a[j];
a[j]=t;
k=j ; //堆被破壞,需要重新調整
}
else //比較左右子結點均大則堆未破壞,不再需要調整
{
break;
}
}
System.out.print("第"+(n-i)+"步排序結果:"); //輸出每步排序的結果
for(h=0;h<n;h++)
{
System.out.print(" "+a[h]); //輸出
}
System.out.print("\n");
}
}
public static void main(String[] args)
{
int[] shuzu=new int[SIZE];
int i;
for(i=0;i<SIZE;i++)
{
shuzu[i]=(int)(100+Math.random()*(100+1)); //初始化陣列
}
System.out.print("排序前的陣列為:\n"); //輸出排序前的陣列
for(i=0;i<SIZE;i++)
{
System.out.print(shuzu[i]+" ");
}
System.out.print("\n");
heapSort(shuzu,SIZE); //排序操作
System.out.print("排序後的陣列為:\n");
for(i=0;i<SIZE;i++)
{
System.out.print(shuzu[i]+" "); //輸出排序後的陣列
}
System.out.print("\n");
}
}
結果如下:
相關文章
- 看懂堆排序——堆與堆排序(三)排序
- python 堆排序Python排序
- js堆排序JS排序
- 堆排序 Heap Sort排序
- 堆排序詳解排序
- 堆排序(C++)排序C++
- js 實現堆排序JS排序
- 堆與堆排序(一)排序
- 排序演算法__堆排序排序演算法
- 排序演算法 - 堆排序排序演算法
- 堆排序(實現c++)排序C++
- 堆排序c++實現排序C++
- 排序演算法-堆排序排序演算法
- 使用 Swift 實現堆排序Swift排序
- 順序表的堆排序排序
- 堆排序就這麼簡單排序
- 二叉堆及堆排序排序
- HDU 1040 As Easy As A+B(堆排序)排序
- C#堆排序演算法C#排序演算法
- 優先佇列和堆排序佇列排序
- 堆的基本操作及堆排序排序
- rust-algorithms:8-堆排序RustGo排序
- 圖解堆排序演算法圖解排序演算法
- 【轉】堆排序Heap Sort——Java實現排序Java
- 堆排序和快速排序效能比較排序
- 從零開始認識堆排序排序
- 堆排序原理及其應用場景排序
- 堆排序你真的學會了嗎?排序
- 線性建堆法與堆排序排序
- PHP 實現堆, 堆排序以及索引堆PHP排序索引
- 【譯】Swift演算法俱樂部-堆排序Swift演算法排序
- 常見演算法 PHP 實現 -- 堆排序演算法PHP排序
- 資料結構與演算法:堆排序資料結構演算法排序
- 資料結構學習筆記-堆排序資料結構筆記排序
- 【資料結構與演算法】堆排序資料結構演算法排序
- 資料結構與演算法——堆排序資料結構演算法排序
- 與堆和堆排序相關的問題排序
- php插入排序,快速排序,歸併排序,堆排序PHP排序