堆排序是一種原地的,時間複雜度為 o(nlogn) 的排序演算法。
快速排序的時間複雜度也是 o(nlogn),甚至堆排序比快速排序的時間複雜度還要穩定,但是快速排序的效能要比堆排序好。
什麼是堆
堆是乙個完全二叉樹。
堆上任一節點的值都大於等於它的左右子樹的值,或者小於等於它的左右子樹的值。
對於每個節點大於等於子樹的堆,叫做大頂堆。對於每個節點小於等於子樹的堆,叫做小頂堆。
圖例如下:
1,2,3屬於堆排序,4不屬於堆排序。
實現堆在總結樹那一篇文章中,提到完全二叉樹適合用陣列的方式儲存資料。所以,對於堆這種完全二叉樹,也用陣列來儲存。
圖例如下:
回顧一下儲存規則:陣列下標為 i 的節點,它的左子節點的下標為 2i,它的右左子節點的下標為 2i+1,它的父節點的下標是 i/2。
下面是一張堆化的過程圖:
**實現如下:
public
class
heap
public
void
insert
(int data)
count++
; heaplist[count]
= data;
int i = count;
while
(i/2
>
0&& heaplist[i]
> heaplist[i/2]
)}//交換
public
void
swap
(int
list,
int i,
int j)
}
public
class
heap
public
void
removemax()
heaplist[1]
= heaplist[count]
; count--
;heapify
(heaplist, count,1)
;}public
void
heapify
(int
heaplist,
int n,
int i)
/** * 這裡 heaplist[i] 替換成了 heaplist[maxpos]
* 如果第乙個條件判斷執行了,那麼本次對比就是對比 左右節點的大小
* 如果第乙個條件判斷沒有執行,那麼本次對比就是對比 父節點和右子節點
*/if(i*2+
1<= n && heaplist[maxpos]
< heaplist[i*2+
1])//均大於左右子節點
if(maxpos == i)
swap
(heaplist, i, maxpos)
; i = maxpos;}}
//交換
public
void
swap
(int
list,
int i,
int j)
}
基於堆實現排序
堆排序的時間複雜是 o(nlogn),而且還是原地排序。
堆排序與快速排序的對比
1:堆排序是跳著訪問陣列中的元素,而快速排序是順序訪問,所以堆排序堆記憶體不友好。
2:在排序的過程中,堆排序的交換過程要遠遠大於快速排序的交換過程。
總結我也漸漸感到很大的壓力了,雖然依舊能讀懂,但是明顯很吃力了。繼續加油吧,如此由淺入深,循序漸進的優質課程少之又少,繼續堅持下去。
初入演算法學習,必是步履蹣跚,一路磕磕絆絆跌跌撞撞。看不懂別慌,也別忙著總結,先讀五遍文章先,無他,唯手熟爾~
與諸君共勉
演算法筆記 堆排序1 0
郭郭自學筆記 1 堆排序1.0 1.堆是什麼 堆其實就是乙個完全二叉樹 特點 2.堆特性的應用 對於給的一組資料,如上圖 16,14,10,8,7,9,3,2,4,1 從大到小排序。如上圖,乙個大根堆,的根節點,明顯是一組資料的最大值。3.堆排序 c 下次我絕對不寫這麼多話了,直接上 include...
演算法筆記之堆排序
一 對堆排序的相關了解 1 堆排序的執行時間是 o nlogn 2 定義 堆heap是一棵具有下面屬性的二叉樹 1 它是一棵全然二叉樹。2 每乙個結點大於或等於它的隨意乙個孩子。備註 全然二叉樹的定義 除了最後一層沒填滿以及最後一層的葉子都是偏左放置的。其它層都是滿的二叉樹!3 二叉堆有兩種 最大堆...
漫畫演算法筆記 堆排序
include include include include include using namespace std 下沉調整 template typename t void downadjust vector vec,int parentindex,int size 如果父節點小於任何乙個孩子...