堆排序演算法是複雜的排序演算法,是不穩定的排序演算法。
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...