堆排序
前一篇寻找第k小的数可以用来处理大量数据,这里介绍的堆排序也可以用来处理大量数据的情况,而且堆排序的思想还可以
找出前k小的数据(自然也可以找出前k大的数据,就看是建立大根或者小根堆了),只需要建立k个数据的堆就行了,然后依次
把后面的数据放入到堆中的适当位置。这里只是实现了堆排序(并没有实现找出前k小的数)。
#include <iostream>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <iterator>
using namespace std;
const int NUM = 25;
void heap_adjust(int a[], int st, int n)///建立大根堆,sift_down
{
int i,t;
while(2 * st + 1 < n) ///改变一个结点需要处理其子树,保证堆的特性
{
i = 2 * st + 1; ///下标从0开始,这里i为左孩子的下标
if(i + 1 < n) ///一开始这里写错了,写成了 i < n,保证有右孩子才进行下面的操作
{
if(a[i] < a[i + 1]) //找出左右孩子中较大的一个的下标
i = i + 1;
}
if(a[st] < a[i])
{
t = a[i];
a[i] = a[st];
a[st] = t;
st = i;
}
else
break;
}
}
void heap_sort(int a[], int n)
{
for(int i = n / 2 - 1; i >= 0; i--)///调整针对非叶结点
heap_adjust(a,i,n);
for(int i = n - 1; i >= 0; i--)///根据大根堆的特性,每次将当前根结点(值最大的)
{ ///放到序列的末尾,对前面的数字(除当前末尾)进行堆调整
int temp = a[0];
a[0] = a[i];
a[i] = temp;
heap_adjust(a,0,i);
}
}
int random_number()
{
return rand() % 100;
}
int main()
{
int a[NUM] = {0};
srand(time(NULL));
generate(a, a + NUM,random_number);
copy(a,a + NUM, ostream_iterator<int>(std::cout ," "));
cout << endl;
heap_sort(a,NUM);
copy(a,a + NUM, ostream_iterator<int>(std::cout ," "));
cout << endl;
return 0;
}