我們學習堆排序之前需要弄清堆的概念,計算機常說的堆有兩種一種是作業系統上的堆記憶體,還有一種是資料結構上的堆,今天我們來講資料結構上的堆,資料結構上的堆也有幾種,二叉堆,二項堆,斐波那契堆,通常我們把二叉堆成為簡稱為堆。
堆排序也是一種效率很高的排序,平均時間複雜度為:o(nlogn)
二叉堆是一種完全二叉樹,其中非葉結點與父節點的關係總滿足,i<=2*1+1&&i<=2*(i+1)或者i>=2*1+1&&i>=2*(i+1)的關係,i為父節點
其中,i<=2*1+1&&i<=2*(i+1)稱為小頂堆,i>=2*1+1&&i>=2*(i+1)稱為大頂堆。
堆排序的思想如下:
首先將指定的一組數轉化成大頂堆或者小頂堆,通過父節點與子節點的比較進行前後替換,通過遞迴遍歷所有節點,每次從頂部取出未排序的最大值跟未排序的最後乙個交換, 例如:堆a[0,n-1],先交換a[0]和a[n-1],調整堆,交換a[0]和a[n-2],調整堆......,交換a[0]和a[1],交換完畢。
得出排序結果。
(初始化堆,迴圈(交換頂部和未排序的最後乙個,調整堆)。
舉個例子:
第一步、給個陣列a[4]=
轉換得一二叉樹
1 2
第二步、堆化,從第乙個非葉結點開始調整,左子節點,1和4交換得
4 2
第三步繼續堆化,3跟4交換得初始大頂堆
3 2
下面為關鍵步驟:
第四步,將最頂的與最後的交換,把最大的放到最後面的節點。
1 3 2
交換了之後,明顯1和3不符合堆的概念,因為需要繼續調整
1 2
4 最頂的和未排序的最後乙個交換,3和2交換得
1 3
2和1交換得
2 3
4 節點訪問完畢,得結果。
關鍵**:
void max_heapify(int*arr,int index,int len)
}
下面給出完整**:
//#include "stdafx.h"
#include#include #define numlen 20000
inline void myswap(int*a,int*b)
void max_heapify(int*arr,int index,int len)
}void build_maxheap(int*arr,int len)
void heap_sort(int*arr,int len)
}int main(int argc, char* argv)
{ int a[numlen];
srand((int)time(null));
for(int i=0;i20000個資料的時間情況:
八大排序之堆排序
public class heapsort heapsort num,num.length for int i 0 i 0 i heapadjust array,i,length 從最後乙個元素開始對序列進行調整,不斷的縮小調整的範圍直到第乙個元素 for i length 1 i 0 i priv...
八大排序之堆排序
public static void heapsort int arr for int i 0 i arr.length i int size arr.length 堆中用size表示長度 swap arr,0,size while size 0 用 3 0 1 5 2 畫圖,過程清晰。陣列最後插入...
八大排序之堆排序
堆排序法 直接選擇排序的改進 將排序碼k1,k2,k3,kn表示成一棵完全二叉樹,然後從第n 2個排序碼開媽篩選,使由該結點組成的子二叉樹符合堆的定義,然後從第n 2 1個排序碼重複剛才操作,直到第乙個排序碼止,這時候,該二叉樹符合堆的定義,初始堆已經建立。接著,可以按如下方法進行堆排序 將堆中第乙...