《数据结构》堆排序

来源:互联网 发布:网络上有重名上不去网 编辑:程序博客网 时间:2024/05/17 07:20

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);//调为大根堆

}

}

原创粉丝点击