c++堆排序(STL+自实现)


#include 
#include 
#include 
using std::endl;
using std::cout;
using std::vector;
struct MaxHeapCmp
{
 bool operator() (const int & lhs, const int & rhs)
 {
  return lhs < rhs;
 }
};
struct MinHeapCmp
{
 bool operator() (const int & lhs, const int & rhs)
 {
  return lhs > rhs;
 }
};
void adapt_heap(int *array, int head, int tail);
void make_max_heap(int* array, int head, int tail);
int main()
{
/*注释掉的为STL提供的堆排序算法,直接调用make_heap()->(迭代器范围和cmp函数对象,默认是“<",即大根堆)可以将序列容器中元素建立成大根堆,(即初始建堆),之后插入数据更新堆时,需要现在容易末尾插入新数据(如push_back),再使用push_heap()更新堆,同理,取堆根位置,需要先pop_heap()此时,会把堆根数据放到容器末尾,然后更新堆【算法自动更新】,你需要使用容器的pop_back等来获取此元素*/
/*vector ivec{1,3,9,7,5,2,6,4,8};
 make_heap(ivec.begin(), ivec.end(), MaxHeapCmp());
 ivec.push_back(10);
 push_heap(ivec.begin(), ivec.end(), MaxHeapCmp());
 cout << "Make a MaxRootHeap" << endl;
 for (int elem : ivec)
 {
  cout << elem << endl;
 }
 cout << endl;
 getchar();*/
 int arr[] = { 1,3,9,7,5,2,6,4,8 };
 make_max_heap(arr, 0, 8);
 for (auto elem : arr)
 {
  cout << elem<<" ";
 }
 getchar();
}
//调整堆
void adapt_heap(int *array, int head, int tail)
{
 using std::swap;
 //从头开始,因为堆排序会把根节点和最末节点数据互换,来实现排序
 int tmp = array[head];
//如果该节点有左子树
 while (head * 2 + 1 <= tail) 
 {
  bool right = 0;//判断是和左子树换位置还是和右子树换位置
  int more = array[head * 2 + 1];
  //如果有右子树,且右子树数据大于左子树
  if((head*2+2)<=tail&&array[head*2+2]>array[head*2+1])
  {
   more = array[head * 2 + 2];
   right = 1;
  }
  //如果孩子节点大于父节点
  if (more < array[head])
  {
   break;
  }
  else if(right)
  {
   swap(array[head * 2 + 2], array[head]);
   head = head * 2 + 2;
  }
  else
  {
   swap(array[head * 2 + 1], array[head]);
   head = head * 2 + 1;
  }
 }
}
//建立大根堆,从最后一个节点的父节点开始,一次往前
void make_max_heap(int* array, int head, int tail)
{
 for (int i = (tail - 1) / 2; i >= 0; i--)
 {
  adapt_heap(array, i, tail);
 }
}

你可能感兴趣的:(数据结构&算法,数据结构,堆排序,c++)