堆的實現及堆排序

2021-08-06 03:17:38 字數 2314 閱讀 4994

前兩天刷筆試題,判斷乙個陣列的序列可以構成堆。仔細想了想,腦海裡幾乎已經遺忘了堆的知識,今天又重新去看書,把堆的知識總結一下。

首先堆是一種陣列物件,它可以被看成乙個完全二叉樹。在我們常見的堆中有大堆和小堆。對大堆來說,每個父節點都大於孩子結點;小堆恰好相反。而且,大堆/小堆的每個子樹也是乙個大堆/小堆。

一般,我們都是用陣列來儲存堆的,當然根據情況,我們也可以選擇用vector來儲存。所以堆的結構如下。也可以很清楚看到父子節點的關係。

在學習乙個新的資料結構,我們一定要很清楚怎樣去建立這個資料結構。下面,我們說說如何建立乙個堆(這裡以大堆為例)。如上圖,可以很明顯看出來堆的整體形狀,然後我們一般是用乙個陣列去構建乙個堆,當然你也可以採用插入的方式去構建堆。在這裡,我們用陣列構建,然後講堆的插入。

1.堆的構建

在給定的陣列裡,我們可以先將所有的葉子結點認為是已經符合要求的子堆,那麼我們需要調整的第乙個堆肯定是最後乙個擁有葉子結點的父節點。如下圖,即是a[4]=13這個結點。在這裡也可以看出父節點和子節點的關係,child=parent*2-1。

我們建的是乙個大堆,在這裡已經是乙個堆的大概形狀了。所以我們需要調整父子關係。如果孩子大於父親,那麼交換父子。然後依次向下調整。原理比較簡單,就不畫圖說明了 。

void _adjustdown(int root)

else

break;}}

堆化陣列就是將所有的資料按照如上所示的方式乙個個調整,直到所有的資料都符合大堆的規則。在這裡,我所建的堆的底層是乙個vector。

heap(t* a, size_t n)  //堆化陣列

//可以把所有的葉子結點看成是 乙個合法的堆

//所以需要從最後乙個結點的父節點開始向下調整

//child=parent*2+1;

for (int i = (_a.size() - 2 / 2); i >= 0; i--)

}

2.堆的插入

上面給出的是對乙個陣列的堆化,那麼如果我們想插入完成乙個堆的建立也是可以的。當我們在乙個堆中插入乙個資料,毫無疑問這個資料是插入在最後的,然後我們通過調整使得堆繼續滿足條件。

如圖,我們插入了11,這個堆已經不滿足條件了,然後我們通過對堆的調整,向上調整。直到把11調整到合適的位置。

void push(const t& x)  //時間複雜度為log(n)

void _adjustup(int child)

else

break;}}

3.堆的刪除

既然有插入,那麼必不可少的也得有刪除。但是堆的刪除,我們需要考慮一下怎麼刪。按照堆的定義,我們只能刪除堆中第0個資料。如果我們直接刪除堆的這個資料,這個堆的結構都發生了改變,那麼我們該怎麼刪除呢?

在我們學習的過程中,有種方法叫做替代法,也就是說將a[0]和a[last]的資料進行交換,然後刪除掉最後乙個資料。刪除最後乙個葉子,對這個堆的結構並不會發生什麼影響,緊接著我們在通過對堆進行乙個調整,保證這個堆仍是乙個大堆/小堆。

//刪除的時間複雜度為log(n)

4.堆排序

說了這麼多堆的基礎知識,那麼堆在我們資料結構中的應用呢?最常見的乙個就是堆排。堆排在我們平常用的概率也是蠻大的。堆排採用的思想是:先對乙個陣列進行建堆,如果這是要公升序,我們就建乙個大堆,然後將堆中最大的資料和最後乙個資料進行交換,將剩下的資料繼續調整為乙個大堆,然後在將最大的數和剩下的數的最後乙個進行交換……依次類推。

void adjustdown(int* a, size_t n, size_t parent)

else

break

; }

}void heapsort(int* a, size_t n)

}

整理堆排的整個思路,我們可以計算出堆排的時間複雜度為n*log(n)。恢復堆的時間複雜度為log(n),對陣列的n個數來說,每次都需要這樣操作一遍,所以時間複雜度為n * log(n)。

堆及堆排序

什麼是堆?堆是一棵完全二叉樹,並滿足 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 ...

堆的性質 堆的實現 堆排序

目錄 一 堆的性質 二 堆的實現 1.儲存方式 2.向堆中插入元素 3.刪除堆頂元素 4.其他操作 5.完整 三 堆排序 1.原地建堆 2.排序 3.完整 4.建堆的複雜度 o n 5.堆排序的複雜度 o nlogn 6.和快速排序的比較 堆是一種特殊的樹。只要滿足以下兩點,它就是乙個堆 第一點,堆...