資料結構與演算法——堆排序
優先佇列可以用以O(NlogN)時間進行排序,基於該思想的演算法叫做堆排序。
建立N個元素的二叉堆(比如是最小堆)需要花費O(N)時間,然後執行N次deleteMin操作,每次都是最小的元素離開堆。將每次離開的最小元素依次存放在另外一個陣列,這樣就得到了一個順序序列。每次deleteMin操作花費O(logN)時間,總的花費時間為O(NlogN);因此堆排序的時間複雜度為O(N)+O(NlogN),也就是O(NlogN)。
我們採取的方法是,將每次deleteMin操作刪除的最小元素,堆縮小了1,我們將刪除的元素放在堆的後面。
比如:堆中有6個元素,第一個deleteMin操作刪除了a1,現在堆中剩了5個元素,因此把a1放在位置6上面。下一次deleteMin操作刪除了a2,現在堆中剩了4個元素,因此把a1放在位置5上面。在最後一次deleteMin操作之後,該陣列將以遞減順序包含這些元素。如果想將這些元素以遞增的順序排序,可以建立最大堆(父結點的值大於子結點的值)。
建立二叉堆的過程見部落格:http://blog.csdn.net/linux_ever/article/details/50488816
原始碼:
/*************************************************************************
> File Name: heapsort.cpp
> Author:
> Mail:
> Created Time: 2016年01月10日 星期日 20時34分07秒
************************************************************************/
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
inline int leftChild(int i)
{
return 2*i+1;//因為該堆是從陣列下標0開始存放值的,和上次建立二叉堆的時候不一樣
}
template<class T>
void percDown(vector<T> & a, int i, int n)
{
int child;
T tmp;
for (tmp = a[i]; leftChild(i) < n; i = child){
child = leftChild(i);
if(child != n-1 && a[child] < a[child + 1])
child++;
if(tmp < a[child])
a[i] = a[child];
else
break;
}
a[i] = tmp;
}
template<class T>
void heapsort(vector<T> & v)
{
for (int i = v.size()/2; i >= 0; --i){//建立二叉堆
percDown(v, i, v.size());
}
for (int j = v.size()-1; j > 0; j--){
swap(v[0], v[j]);//刪除最大值
percDown(v, 0, j);
}
}
int main()
{
vector<int> v;
v.push_back(97);
v.push_back(53);
v.push_back(28);
v.push_back(33);
v.push_back(23);
v.push_back(77);
v.push_back(89);
v.push_back(-8);
v.push_back(10);
cout << "v: ";
copy(v.begin(), v.end(), ostream_iterator<int> (cout, " "));
cout << endl;
heapsort(v);
cout << "sorted v: ";
copy(v.begin(), v.end(), ostream_iterator<int> (cout, " "));
cout << endl;
return 0;
}
下面是一個下濾的過程圖
相關文章
- 資料結構與演算法:堆排序資料結構演算法排序
- 【資料結構與演算法】堆排序資料結構演算法排序
- 演算法與資料結構之原地堆排序演算法資料結構排序
- 【演算法與資料結構專場】堆排序是什麼鬼?演算法資料結構排序
- 資料結構與演算法-資料結構(棧)資料結構演算法
- 資料結構與演算法資料結構演算法
- 資料結構:初識(資料結構、演算法與演算法分析)資料結構演算法
- 資料結構學習筆記-堆排序資料結構筆記排序
- 資料結構與演算法:圖形結構資料結構演算法
- python演算法與資料結構-什麼是資料結構Python演算法資料結構
- 資料結構與演算法02資料結構演算法
- 資料結構與演算法-堆資料結構演算法
- 資料結構與演算法03資料結構演算法
- 【JavaScript 演算法與資料結構】JavaScript演算法資料結構
- 資料結構與演算法(java)資料結構演算法Java
- python資料結構與演算法Python資料結構演算法
- 資料結構與演算法——字串資料結構演算法字串
- 資料結構與演算法——排序資料結構演算法排序
- 演算法與資料結構——序演算法資料結構
- 資料結構與演算法——概述資料結構演算法
- 【資料結構與演算法】bitmap資料結構演算法
- 資料結構與演算法 - 串資料結構演算法
- 資料結構與演算法(1)資料結構演算法
- 高階資料結構---堆樹和堆排序資料結構排序
- 資料結構初階--堆排序+TOPK問題資料結構排序TopK
- python演算法與資料結構-演算法和資料結構介紹(31)Python演算法資料結構
- 資料結構與演算法之線性結構資料結構演算法
- 資料結構與演算法-連結串列資料結構演算法
- [資料結構與演算法] 排序演算法資料結構演算法排序
- javascript資料結構與演算法-棧JavaScript資料結構演算法
- 資料結構與演算法之美資料結構演算法
- 演算法與資料結構1800題演算法資料結構
- JavaScript資料結構與演算法(串)JavaScript資料結構演算法
- [資料結構與演算法] 邂逅棧資料結構演算法
- 資料結構與演算法分析——棧資料結構演算法
- 資料結構與演算法(八):排序資料結構演算法排序
- 【資料結構與演算法】字串匹配資料結構演算法字串匹配
- 演算法與資料結構之集合演算法資料結構