???????堆的基本操作參考文章:[堆的基本操作](http://blog.csdn.net/u013074465/article/details/46741421)
?????? 對于小根堆來說,一般的思路是每次刪除最小值,執行N次刪除;每次將刪除的元素拷貝到一個新的數組,那么新數組將按照從小到大的順序排列。這里的主要問題是空間的:使用新數組,使存儲空間增加了一倍。
?????? 一個技巧是:每次刪除一個堆元素,堆大小會減少1。那么位于堆最后的那個空間可以用來存放剛剛被刪除的元素。按照這種思路,不用額外的空間即可完成排序。
????? 對小根堆,該方式排序完的數組是遞減的,那么,如果我們建立堆時用大根堆,則該方式得到的排序結果是遞增的。
????? 堆排序中用到了下濾操作,因為堆排序其實就是堆刪除的一系列操作,而堆的刪除操作會下濾,參考[二叉堆的插入刪除等操作C++實現](http://blog.csdn.net/u013074465/article/details/42028473)
????? 在移動堆元素的時候(AdjustHeap函數中),用到了一個技巧來減少交換元素的次數,參考[插入排序和希爾排序](http://blog.csdn.net/u013074465/article/details/42043665),這里不再贅述。
~~~
/*
(大根)堆排序,花費O(NlogN)。
*/
template<typename T>
void HeapSort(vector<T>& a) {
int i;
//先建立大根堆,該操作花費O(N)
for (i = a.size() / 2; i >= 0; --i) {
AdjustHeap(a, i, a.size());
}
//將要刪除的元素放入堆末尾的空間(交換根元素和尾元素),
//這樣不需要額外的空間。
for (i = a.size() - 1; i > 0; --i) {
T tmp = a[i];
a[i] = a[0];
a[0] = tmp;
/*
每次刪除時,根元素與根末尾元素交換了,在位置0處下濾。
由于不斷從堆中刪除,因此堆大小不斷減小,為i
*/
AdjustHeap(a, 0, i);
}
}
//該函數是堆操作中的下濾操作
template<typename T>
void AdjustHeap(vector<T>&a, int pos, int n) {
int pos_child;
T tmp;
for (tmp = a[pos]; (pos * 2 + 1) < n; pos = pos_child) {
pos_child = 2 * pos + 1;
if (pos_child != n -1 && a[pos_child] < a[pos_child + 1])
pos_child++;
if (tmp < a[pos_child])
a[pos] = a[pos_child];
else
break;
}
a[pos] = tmp;
}
//只是一個打印元素的函數
template<typename T>
void PrintValue(vector<T>& a) {
?vector<T>::iterator iter = a.begin();
?while (iter != a.end()) {
??? ?cout << *iter++ << " ";
?}
?cout << endl;
}
int main() {
?int value;
?vector<int> ivec;
?while (cin >> value)
??? ?ivec.push_back(value);
?HeapSort<int>(ivec);
?PrintValue(ivec);
}
~~~

- 前言
- Josephus約瑟夫問題及其變種
- 鏈表的常見實現
- 二叉樹遍歷、插入、刪除等常見操作
- 二叉堆的插入刪除等操作C++實現
- 插入排序和希爾排序
- 堆排序
- 歸并排序及其空間復雜度的思考
- 快速排序的幾種常見實現及其性能對比
- 紅黑樹操作及實現
- 整數的二進制表示中1的個數
- 位操作實現加減乘除四則運算
- 冒泡排序的改進
- 直接選擇排序
- 不借助變量交換兩個數
- 基礎排序算法總結
- AVL樹(Adelson-Velskii-Landis tree)
- avl樹的C++實現
- 動態規劃之鋼條分割
- hash函數的基本知識
- 動態規劃:求最長公共子串/最長公共子序列
- 最長遞增子序列
- 稱砝碼問題
- 汽水瓶
- 字符串合并處理(二進制位的倒序)
- 動態規劃:計算字符串相似度
- m個蘋果放入n個盤子
- 生成k個小于n的互不相同的隨機數
- 棧和隊列的相互模擬
- 字符串的排列/組合
- KMP(Knuth-Morris-Pratt)算法
- n個骰子的點數
- 位運算的常見操作和題目