堆排序

前一篇寻找第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;
}

原文地址:https://www.cnblogs.com/zhuyp1015/p/2483166.html