複習資料結構:排序演算法(六)——堆排序
對於堆排序,前面一篇博文中已經複習到了堆排序,這裡就簡單介紹一下,並給出核心部分的解釋。
堆排序是一種不穩定的排序,也是內排序。
時間複雜度為O(nlogn)。
以最大堆為例,堆排序的基本思想是:
1)將初始待排序關鍵字序列(R1,R2....Rn)構建成大頂堆,此堆為初始的無序區;
2)將堆頂元素R[1]與最後一個元素R[n]交換,此時得到新的無序區(R1,R2,......Rn-1)和新的有序區(Rn),且滿足R[1,2...n-1]<=R[n];
3)由於交換後新的堆頂R[1]可能違反堆的性質,因此需要對當前無序區(R1,R2,......Rn-1)調整為新堆,然後再次將R[1]與無序區最後一個元素交換,得到新的無序區(R1,R2....Rn-2)和新的有序區(Rn-1,Rn)。不斷重複此過程直到有序區的元素個數為n-1,則整個排序過程完成。
其實,堆排序最重要的兩部分就是:初始化堆和調整堆。
程式碼如下:
#include<iostream>
#include<algorithm>
using namespace std;
// 調整堆函式
void HeapAdjust(int *a, int i, int size) // a:陣列;i:節點index;size:樹的規模
{
int lchild = 2 * i; // 節點的左孩子編號
int rchild = 2 * i + 1; // 節點的右孩子編號
int max = i; //節點編號備份
if(i <= size/2 - 1)
{
if(lchild <= size && a[lchild] > a[max]) // 左孩子比節點值要大
max = lchild;
if(rchild <= size && a[rchild] > a[max]) // 右孩子比節點值要大
max = rchild;
if(max != i) // 如果上面發生了交換,也就是如果上面有if成立了
{
swap(a[i], a[max]); // 首先要交換二者的真實值,因為上面只是index的交換
HeapAdjust(a, max, size); // 其次,需要判斷交換之後還需要重新調整嗎
}
}
}
//建立堆函式
void BuildHeap(int *a, int size)
{
int i;
for(i = size/2 - 1; i >= 0; i--) // 非葉子節點最大序號值為size/2,需要遍歷所有的節點
{
HeapAdjust(a, i, size); // 調整
}
}
// 堆排序函式
void HeapSort(int *a, int size)
{
int i;
BuildHeap(a, size);
for(i = size; i >= 0; i--)
{
swap(a[0], a[i]); // 交換堆頂和最後一個元素,每次將剩餘元素中的最大者放到最後面
HeapAdjust(a, 0, i-1); // 重新調整堆頂節點成為大頂堆,這個時候就要除出最後一個元素,範圍是1~n-1
}
}
int main()
{
int a[] = {100, 16, 20, 3, 11, 17, 8};
int size = 7;
HeapSort(a, size);
for(int i = 0; i < size; i++)
{
cout<<a[i]<<endl;
}
cout<<endl;
return 0;
}
參考連結:
http://blog.csdn.net/puqutogether/article/details/43195703
http://blog.csdn.net/hguisu/article/details/7776068
http://blog.csdn.net/xiazdong/article/details/8462393
http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html
相關文章
- 資料結構與演算法:堆排序資料結構演算法排序
- 【資料結構與演算法】堆排序資料結構演算法排序
- 資料結構與演算法——堆排序資料結構演算法排序
- 資料結構學習筆記-堆排序資料結構筆記排序
- 演算法與資料結構之原地堆排序演算法資料結構排序
- 【演算法與資料結構專場】堆排序是什麼鬼?演算法資料結構排序
- 高階資料結構---堆樹和堆排序資料結構排序
- 資料結構初階--堆排序+TOPK問題資料結構排序TopK
- 資料結構之堆 → 不要侷限於堆排序資料結構排序
- 演算法複習 - AcWing - 資料結構演算法資料結構
- 排序演算法__堆排序排序演算法
- 排序演算法 - 堆排序排序演算法
- 排序演算法-堆排序排序演算法
- 資料結構與演算法——排序資料結構演算法排序
- 演算法與資料結構系列 ( 六 ) - 氣泡排序法- Bubble Sort演算法資料結構排序
- 對資料結構和演算法的總結和思考(六)--計數排序資料結構演算法排序
- 學習javascript資料結構與演算法(六)——圖JavaScript資料結構演算法
- 演算法學習之選擇排序和堆排序:演算法排序
- 資料結構與演算法——排序演算法-歸併排序資料結構演算法排序
- 資料結構與演算法——排序演算法-基數排序資料結構演算法排序
- 資料結構與演算法——排序演算法-氣泡排序資料結構演算法排序
- 資料結構與演算法——排序演算法-選擇排序資料結構演算法排序
- [資料結構與演算法] 排序演算法資料結構演算法排序
- 資料結構與演算法(八):排序資料結構演算法排序
- 資料結構與演算法之排序資料結構演算法排序
- 資料結構與演算法----# 一、排序資料結構演算法排序
- 資料結構與演算法學習-複雜度分析資料結構演算法複雜度
- 排序演算法:堆排序的實現和時間複雜度分析排序演算法時間複雜度
- 資料結構與演算法 基礎排序資料結構演算法排序
- 資料結構與演算法 進階排序資料結構演算法排序
- Java資料結構與排序演算法 (三)Java資料結構排序演算法
- Java資料結構與排序演算法 (一)Java資料結構排序演算法
- Java資料結構與排序演算法 (二)Java資料結構排序演算法
- 資料結構與演算法-反轉排序資料結構演算法排序
- 【資料結構與演算法】歸併排序資料結構演算法排序
- 資料結構與演算法之快速排序資料結構演算法排序
- [資料結構拾遺]字串排序演算法總結資料結構字串排序演算法
- 資料結構與演算法整理總結---排序 2資料結構演算法排序
- 資料結構和演算法(六)佇列資料結構演算法佇列