堆 heap 排序演算法

2021-07-15 00:24:09 字數 2688 閱讀 7365

堆排序演算法是複雜的排序演算法,是不穩定的排序演算法。

1、堆排序的基本思想

堆排序定義:n個有序列a1,a2,...,an成為堆,有下面兩種不同型別的堆。

大根堆:所有子節點都大於其父節點,即ai<=a2i且ai<=a2i+1。

小根堆:所有子節點都小於其父節點,即ai>=a2i且ai>=a2i+1。

若將此序列所儲存的向量a[1...n]看為一顆完全二叉樹的儲存結構,則對實質上是滿足如下性質的完全二叉樹:樹中任一非葉子結點的關鍵字均不大於(或者不小於)其左、右子節點(若存在)的關鍵字。

因此堆排序(heapsort)是樹形選擇排序。在排序過程中,將r[1...n]看成一棵完全二叉樹的順序儲存結構,利用完全二叉樹中雙親節點和孩子節點之間的內在的關係,在當前無序區中選擇關鍵字最大的(最小的)記錄。

用大根堆排序的基本思想:

(1) 先將初始a[1...n]建成乙個大根堆,此堆為初始化無序區。

(2) 再將關鍵字最大的記錄a[1](堆頂)和無序區的最後乙個記錄a[n]交換,由此得到新的無序區a[1...n-1]和有序區a[n],且滿足a[1...n-1] <= a[n].

(3) 由於交換後新的根a[1]可能違反堆性質,所以將當前無序區a[1...n-1]調整為堆。然後再次將a[1...n-1]中關鍵字最大的記錄a[1]和該區間的最後乙個記錄a[n-1]交換,由此得到新的無序區a[1...n-2]和有序區a[n-1...n],且仍滿足關係a[1...n-2] <= a[n-1...n],同樣要將a[1...n-2]調整為堆。

(4) 對調整的對重複進行上面的交換,直到無序區只有乙個元素為止。

2、思想

利用完全二叉樹中雙親節點和孩子節點之間的內在關係,在當前無序區中選擇關鍵字最大(或者最小)的記錄。也就是說,以最小堆為例,根節點為最小元素,較大的節點偏向於分布在堆底附近。

3、演算法複雜度

最壞情況下,接近於最差情況下:o(n*logn),因此它是一種效果不錯的排序演算法。

4、穩定性

堆排序需要不斷地調整堆,因此它是一種不穩定的排序!

5、**實現

//程式設計實現堆排序

//堆排序是較為複雜的排序。

//1.首先是將整個陣列進行乙個初始化堆操作,是將所有的節點進行堆化(所有的父節點都是自己左右子節點中最大的)

//2.進行堆化之前首先是記錄一下堆化的大小(heapsize=len),確定整個陣列最後乙個父節點(i=len>>1),從最後乙個父節點進行遍歷到0最頂的父節點(i>=0,i--)

//3.堆化中,首先確定左右子節點索引,largest記錄的是左右節點中最大元素的索引,前提條件為:左右子節點索引小於heapsize的(不然沒有意義)

//4.先比較左節點與父節點array[left] > array[index]找出最大值賦值給largest,再比較array[right] > array[largest]找到三者最大值

//5.若父節點不是最大值,則交換父節點與largest的位置,在遞迴進行堆化。直到整個二叉樹完全符合大根堆

//6.完成堆化之後,交換最後乙個數與堆頂的位置,堆大小-1,在重新在最頂端進行堆化(maxheapify(array,0))

//7.重複3-7步驟,完成堆排序。

#includeusing namespace std;

static int heapsize = 0;

//返回左子節點索引

int left(int index)

//返回右子節點索引

int right(int index)

//交換a、b的值

static void swap(int *a, int *b)

//array[index]與其左、右子樹進行遞迴對比

//用最大主替換array[index],index表示堆頂索引

void maxheapify(int array, int index)

else

//把largest與堆頂的柚子節點比較,去較大者

if ((right <= heapsize) && (array[right] > array[largest]))

//此時largest為堆頂、左子節點、右子節點三者中最大者

if (largest != index) }

//初始化堆,將陣列中的每乙個元素只放到適當的位置

//完成之後,最頂的元素為陣列的最大值

void buildmaxheap(int array, int len)

}void heap_sort(int array, int len)

}void print_array(int a, int length)

}void main9mian****i6()

; cout << "before heap sort:";

print_array(a, 8);

heap_sort(a, 8);

cout << "\nafter heap sort:";

print_array(a, 8);

system("pause");

}

6、測試結果

before heap sort:45 68 20 39 88 97 46 59

after heap sort:20 39 45 46 59 58 88 97

STL中heap演算法(堆演算法)

push heap演算法 以下是push heap演算法的實現細節。該函式接收兩個迭代器,用來表現乙個heap底部容器 vector 的頭尾,而且新元素已經插入究竟部的最尾端。template inline void push heap randomaccessiterator first,rand...

堆 heap 的定義及其演算法分析

堆 heap 是與二叉查詢樹類似的adt。但又不同於二叉查詢樹,主要體現在兩個方面。第一,可將二叉查詢樹看著是有序的,而堆是有序的,這一概念較弱。不過,為使優先佇列操作有效執行,這完全滿足要求。第二,二叉查詢樹有多種不同形狀,而堆總是完全二叉樹。堆是完全二叉樹,可以為空,或者 1 根包含的查詢關鍵字...

堆(Heap)的實現

這次實現了堆,這個堆不是指系統堆疊的堆,是一種資料結構,見下圖 堆的本質就是乙個陣列 上圖中,紅色的是值,黑色的是下標 簡單的來說就是把乙個陣列看成是二叉樹,就像上圖 大堆和小堆分別是指根節點比孩子節點的值大或者是小,看了上圖之後就可以發現,父親節點和孩子節點之間下表的關係,parnet child...