堆排序基礎

2021-06-07 17:49:20 字數 1970 閱讀 1528

首先,推薦大家去看下《演算法導論》,那是演算法聖經,講得非常詳細,本文中的**大部分是將其中的偽**用c/c++實現出來

雖然書上有堆排序(heapsort)的概念的詳細解釋,網路上介紹堆排序的講解也基本都有描述,我這還是將一些基本概念寫出來:

:(二叉)堆資料結構是一種陣列物件,可以被視為一棵完全二叉樹,樹中的每個結點與陣列中存放該結點值的那個元素對應。如下圖所示:

假設儲存陣列下標從1開始,則給定某個結點的標 i, 易得其父結點下標為 ⌊i / 2⌋, 左兒子結點下標為 2 * i,右結點下標為2 * i + 1

二叉堆有兩種:最大堆和最小堆(小根堆),上圖即為最大堆及其陣列表示

最大堆:在最大堆中,最大堆特性是指除了根以外的每個結點 i ,有 a[parent( i )] ≥ a[ i ](parent(i)是指 i 結點的父結點), 即某個結點的值至多是和其父結點的值一樣大,這樣,堆中的最大元素就存放在根結點中;並且,在以某乙個結點為根的子樹中,各結點的值都不大於該子樹結點的值

最小堆:組織方式與最大堆正好相反;最小堆特性就是除了根以外的每個結點i,有a[parent( i )] ≤ a[ i ],最小元素在根部

堆排序:堆排序的實現利用了最大堆(最小堆)的「堆的最大(小)元素就存放在根結點中」這一特性,可以在每次堆化後盡快地找到當前堆的最大(小)元素

在堆排序中,通常使用的是最大堆,而最小堆通常在構造優先佇列時使用,關於優先佇列的實現後面的總結中會出現

堆排序的執行時間為o(n lgn),是一種原地排序演算法:在任何時候,陣列中只有常數個元素儲存在輸入陣列以外

具體實現看以下**:

/*

***author: asd

***data: 2012/7/13

***blog:

***heapsort

*/#include using namespace std;

//利用異或交換 a, b 的值

#define swap(a, b)

//輸出 a[1..size] 的值

void arr_display(int *a, int size)

//呼叫是假定 a[left], a[right] 為根的兩棵二叉樹都是已成最大堆

//但是a[i]可能小於它的子節點,違反了最大堆的性質

//max_heapify使a[i]在最大堆中「下降」,使以i為根的子樹成為最大堆

void max_heapify(int *a, int size, int i)

}//自底向上地將乙個陣列a[1..n]變成乙個最大堆

//在陣列a[1..n]中,a[(n / 2) + 1..n]是樹中的葉子

//每個都是只含乙個元素的堆,對其他結點(也就是非葉子結點)都呼叫一次max_heapify

void build_max_heap(int *a, int size)

//先將陣列a[1..n]用build_max_heap構造成乙個最大堆

//因為a[1]為堆中最大的元素,所以可以通過其與a[n]交換,使其到達最終正確的位置

//然後在堆中去掉交換後的結點n,因為結點1為根的子女仍然還是最大堆

//而交換後的結點1可能就違背了最大堆的性質,只要用max_heapify進行維護

//使a[1..n-1]仍然為最大堆,然後又交換a[1]與a[n-1],再呼叫max_heapify

//重複這個過程可使堆的大小從n-1一直降到2,這時a[1..n]即為原陣列按非降序排序結果

void heapsort(int *a, int size)

}int main()

最後,再次提醒,去看看《演算法導論》的第六章,其中的內容非常詳細

演算法基礎 排序 堆排序

headsort2 是我自己想的,感覺這麼寫可以。驗證是ok的。區別等我問問。import com.alibaba.fastjson.json author wangtb date 2019 09 29 23 02 public class heapsort heapsort arr heapsor...

夯實基礎 堆排序

堆結構 任意的乙個父節點大於其子節點。邏輯結構 二叉樹 物理結構 陣列 如果從角標0開始 父節點左孩子節點 2 i 1 父節點右孩子節點 2 i 2 最後乙個非葉節點 n 1 2 如果從角標1開始 父節點左孩子節點 2 i 父節點右孩子節點 2 i 1 最後乙個非葉節點 n 2 堆排序分析 最優時間...

C 基礎 堆排序

首先呢,希望學習堆排序的各位千萬不要以為這個演算法有多麼的難,可以理解為 構造樹 堆排序的過程就是構造樹的過程。這裡先指明三個公式 假設當前節點下標為i,則 排序的過程 假設待排序陣列為int a 10 1.遍歷所有非葉子的節點,建立大根堆 小根堆的完全二叉樹 2.將樹的根節點 a 0 與最後的子節...