堆排序问题

堆排序问题

在说堆排序之前,必须得弄清楚什么是堆?堆就是一种特殊的完全二叉树,而它具有一些特点。堆又分为最小堆和最大堆,如果所有的父节点都比子节点小,则这样的堆称为最小堆,反之,则为最大堆。我们开始先创建一个最小堆,首先我们从叶节点开始,因为叶节点没有儿子,所以所有的叶节点都符合最小堆特征。于是就得从最后一个非叶节点开始,直到根节点,逐渐调整它们的位置。
创建堆代码如下:

void create()
{
  for(int i = n / 2; i >= 1; i --)
     shiftdown(i);
   return; 
}

shiftdown函数作用便是调整位置,从父节点开始,若发现它最小的子节点的值比它还小,便把它和父节点交换位置,直到父节点为叶节点为止。

void shiftdown(int i)
{
 int t ,flag = 0;
 while(i * 2 <= n && flag == 0)
 {
  
     if(h[i] > h[i * 2])
     t = i * 2;
     else
     t = i;
  
  if(i * 2 + 1 <= n )
  {
     if(h[t] > h[i * 2 + 1])
     t = i * 2 + 1;
  }
  if(t != i)
  {
    swap(i,t);
    i = t;
  }else
  flag = 1; 
 }
 return;
}

还有一个问题,如何让它由小到大排序输出呢?可以每次输出h[1]后,把最后一个叶节点赋值给h[1],再重新调整位置即可。输出过后每次删除一个节点。

int deletemax()
{
   int t;
   t = h[1];
   h[1] = h[n];
   n --;
   shiftdown(1);
   return t;
}

main函数如下:

int main()
{
   int num;
   cin >> n;
   num = n;
   for(int i = 1; i <= n; i ++)
      scanf("%d",&h[i]);
   create();
   for(int i = 1; i <= num; i ++)
   cout << deletemax() << " ";
   return 0;
} 

也可以先建立最大堆,最大元素在h[1],我们的需求是从小到大排序,希望最大的放在最后。因此我们把h[1]和h[n]交换,因此h[n]便是最大的数,交换后h[1]相下调整以保持堆得特性。
排序函数如下:

void heapsort()
{
   while(n > 1)
   {
     swap(1,n);
     n --;
     shiftdown(1); 
   }
  
}

main函数如下:

int main()
{
   int num;
   cin >> n;
   num = n;
   for(int i = 1; i <= n; i ++)
      scanf("%d",&h[i]);
   create();
   heapsort();
   for(int i = 1; i <= num; i ++)
   cout <<  h[i] << " ";
   return 0;
} 

学了堆排序,发现最大好处就是效率高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值