《数据结构》堆排序

8.4.2堆排序

堆排序是一种树形选择排序,一个二叉树,根节点大于左右子节点。满足:大根堆

根堆  

按照书上给的例子,就用大根堆来描述堆的思想。

什么是大根堆了?只要根节点值大于或者等于左右子节点的值就是大根堆。下面是堆排序列子:

书上的数分别是:

49   38   65   97   76   13   27   49

构造一个二叉树是(画圆直线太麻烦了,就省略了):

                49

            38       65

      97      76  13     27

  49

把这个无序的二叉树调整一下,调为大根堆

总共8个个数,从第4个数(因为根据完全二叉树性质,任意一个根节点为K它的左右子节点一定为2k2k+1)开始,97,97>=49不调往上第3个数开始,65,65>=27(27>13所以只需比较2765大小)再往上第2个数38,38<=97(97>=76),97上去38下来,因为38<=49所以调位,49上去,38再次下来成为最后一个数,

   

                49

            97       65

      49      76  13     27

  38

往上第2个数是97,比左右子节点都大,不调,往上第1个数,49,49<=97(97>=65),4997调位,49<=76再次调位,49>=38不调了。

 

                  97

            76       65

      49      49  13     27

  38

完成!依次类推看以下图(圆圈直线太难画往后就省了):

 

 

 

 

 

 

 

 

                      新堆

大根堆

 

 

 

 

 

 

 

   

 

新堆

    13                       49

49      27               13        27

38    49  65     76      38    49  65    76

97                     97           新堆

 

         49                      13    

     49      27             49        27

 38    13  65     76     38    49   65   76

97                    97            新堆

 

 

 

             49                        49

13      27                38        27

 38   49   65    76        13    49  65      76

97                       97

           13                        27

     38          27              38        13

 49      49  65      76      49      49  65   76

97                          97

         新堆

           38                        13

      27         13             27          38

  49      49   65     76    49      49   65     76

97                        97

                                     新堆

 

           27                           13

     13          38              27           38

49       49  65       76    49        49  65     76

97                        97

                                        新堆

            13

     27              38

 49     49     65        76

97

        新堆

堆排序是不稳定排序,只能用于顺序结构,不能用于链式结构。

 

代码:

//调整堆 调整为大根堆

void HeapAdjust(SqList &L,int s,int m)

{

    RedType rc;

int i,j;

rc=L.r[s];

for(j=2*s;j<=m;j*=2)

{

if(j<m&&L.r[j].key<L.r[j+1].key)//左右子节点数比较右边大j++,左边大正好是j

j++;

if(rc.key>=L.r[j].key)//根节点数大于等于子节点的最大数则不用调位否则调位

break;

L.r[s]=L.r[j];

s=j;

}

L.r[s]=rc;//把需要调位的根节点数,放在合适位置

}

//建初堆

void CreatHeap(SqList &L)

{

int n,i;

n=L.length;

for(i=n/2;i>0;i--)//n/2依次向上调根节点位置一直到最顶端,第一个数

{

HeapAdjust(L,i,n);//执行调位,调为大根堆

}

}

void HeapSort(SqList &L)

{

RedType x;

int i;

CreatHeap(L);//把无序的完全二叉树建立大根堆

for(i=L.length;i>1;i--)//书中H.length印刷错误,应该是L.length

{             //最后一个数和最上面一个数互换

           x=L.r[1];

   L.r[1]=L.r[i];

   L.r[i]=x;

   HeapAdjust(L,1,i-1);//调为大根堆

}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

樊高

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值