面試必問之堆排序及堆

2021-06-21 20:31:00 字數 1930 閱讀 3176

「堆排序(heapsort)是指利用堆積樹(堆)這種資料結構所設計的一種排序演算法」,時間複雜度是o(nlogn),是基於關鍵字比較排序演算法裡比較理想的排序演算法(另個是快速排序),空間複雜度o(1).

堆分為最大堆和最小堆,最大堆的根節點最大,最小堆的根節點最小;最大堆用於遞增堆排序,最小堆用於遞減堆排序,下文提到的堆是指最大堆。

堆排序的實現可以分為兩個子演算法:初始建堆和進行堆排序,我見過兩種堆排序的實現方法,其中進行堆排序的演算法大同小異,主要是初始建堆略有不同。

upheap(a,i):陣列a中第1~i-1個元素符合對結構,加入第i個元素後進行的堆結構調整,使1~i元素復合堆結構。這個演算法很容易實現,時間複雜度是o(logi)。

初始建堆時,逐漸加入元素即可實現初始建堆的功能;(堆排序中,元素是從左到右進行1到n的編號,對應到陣列的相應index,這是為了根節點下標和其左右子結點的下標更好的對應關係)

for(int i=1;i<=n;i++)

upheap(a,i);

所以初始建堆的複雜度是o(nlogn);

heapadjust(a,n):堆結構調整,第1個元素的左右子樹(2~n範圍內)是堆結構,調整元素使陣列a[1]~a[n]整個是個堆結構(即,出來堆頂元素不符合堆的要求,其子樹都是堆),其時間複雜度是o(logn)。

進行堆排序:初始建堆後,將堆頂元素和最後乙個元素對換,然後對前n-1個元素堆結構調整;

for(i=n;i>1;i--)

所以進行堆排序的時間複雜度也是o(nlogn);總體對排序的複雜度就是o(nlogn)。

方法二和方法一的主要區別是初始建堆上,初始化堆時是對所有的非葉子結點進行篩選。

最後乙個非葉子節點的下標是[n/2]向下取整,篩選只需要從第[n/2]向下取整個元素開始,從後往前進行調整。

從最後乙個非葉子結點開始,每次都是從父結點、左孩子、右孩子中進行比較交換,交換可能會引起孩子結點不滿足堆的性質,所以每次交換之後需要重新對被交換的孩子結點進行調整。此處的堆結構調整和方法一的類似.

heapadjust(a,i,n):堆結構調整,第i個元素的左右子樹(i+1~n外圍內)是堆結構,調整元素是陣列a[i]~a[n]整個是個堆結構;思想是找出第i個元素的左右子結點總最大的節點(下標m),然後和節點i比較,若元素i大,則停止,負責將節點m和節點i交換,遞迴調整節點m的堆結構heapadjust(a,m,n),具體實現見時間複雜度為o(logn)。

初始建堆演算法:

int ifirst=(n-1)/2; //第乙個非葉子節點  

for (;ifirst>=0;ifirst--)

進行堆排序演算法:

for (int i=n;i>1;i--)  

容易看出進行堆排序的演算法時間複雜度是o(nlogn),初始建堆時間複雜度貌似也是o(nlogn),所以總體堆排序的複雜度是o(nlogn)。

但是!此方法初始建堆的時間複雜度並不是o(nlogn),而是o(n)!  具體證明可參考

最大的優點是   時間複雜度是o(nlogn),空間複雜度o(1),所以可以用於對時間可空間都要求嚴格的排序。

另外堆排序中的堆結構很適合從大數量資料中選出最大或最小的固定數目的元素,其中要選出最大的k個元素,只需要遍歷一遍,並維持乙個k大小的最小堆(堆頂元素最小),遍歷到元素i時,如果元素i比堆頂元素大,則將堆頂元素換成元素i並調整堆結構,否則繼續遍歷元素i+1,時間複雜是o(nlogk).

c++中優先佇列(priority_queue)的內部實現就用到了堆,優先佇列的pop()函式就是將堆頂元素刪除,調整堆結構使得堆頂元素最小(或最大),push()函式就是加入乙個元素,調整堆結構。

堆及堆排序

什麼是堆?堆是一棵完全二叉樹,並滿足 n od ei n ode2 i 1 andn odei n ode2 i 2 node quad and quad node i node nodei n ode2 i 1 and node i n ode2 i 2 大頂堆 或者nod ei n ode2 i...

堆及堆排序

堆是一種特殊的資料結構,它是完全二叉樹,可以用一維陣列來儲存,因為二叉樹的性質,所以根據陣列下標就可以確定位置,下面 是關於堆的實現,刪除的過程其實就是將堆的根節點取出的過程,這時的順序就是有序的,如果是最小堆,那麼就是從小到大排序,反之,就是從大到小 1 include 2 3int h 101 ...

面試常問 堆排序

思路 分析 改進 思路 堆排序有兩種,一種利用堆的特性,先構建最大堆,每次得到最大堆的堆頂元素 另一種是直接原地使用堆排序。原地堆排序 將陣列構建成堆,交換陣列的第乙個元素和最後乙個元素。依次對除去最後的元素的剩下陣列進行排序。原地排序 public class main heapsort arr,...