原理:
其实就是选择排序,不同的是用数据结构里的堆来代替原来的线性表。
(1) 建堆 ( O(n) )
(2)取出堆顶放在已排序列最前,并调整复原堆 ( O(log n) )
int find_father(int i){
// 寻找秩为i的父节点的秩
if((i+1)%2==1)
return (i-1)/2;
else
return i/2;
}
void max_heap(int * a, int start, int end) {
// 调整a[start,end)数组为顶大的堆
int b[end-start+1];
b[0]=a[0];
for(int i=start+1;i<end;i++){
// 每次把a的一个元素加入到堆中
// 将新加入的元素上滤到正确的位置
b[i]=a[i];
int y=i;
// 如果当前元素比它的父元素大,交换
while(b[y]>b[find_father(y)])
{
swap(b[y], b[find_father(y)]);
y=find_father(y);
}
}
// 将更新过的堆复制给原数组
for(int i=start;i<end;i++){
*a=b[i];a++;
}
}
void HeapSort(int a[], int len) {
// 建堆
max_heap(a, 0, len);
// 每次将堆顶元素与当前区间前一个元素交换
// 然后缩小区间更新堆
for(int i=len-1;i>0;i--){
swap(a[0], a[i]);
max_heap(a, 0, i);
}
}
另一种方法
调用C++库函数
#include<iostream>
#include <algorithm> //std::make_heap, std::pop_heap, std::push_heap, std::sort_heap
#include<vector>
using namespace std;
int main () {
int a[] = {10,20,30,5,15};
vector<int> v(a,a+5);
// 建堆
make_heap (v.begin(),v.end());
cout << "initial max heap : " << v.front() << endl;
// 删除堆顶
pop_heap (v.begin(),v.end()); v.pop_back();
cout << "max heap after pop : " << v.front() << endl;
v.push_back(99); std::push_heap (v.begin(),v.end());
cout << "max heap after push: " << v.front() << endl;
// 堆排序
sort_heap (v.begin(),v.end());
cout << "final sorted range :";
for (unsigned i=0; i<v.size(); i++)
cout << ' ' << v[i];
cout << endl;
return 0;
}