堆排序算法,附图与C++代码

堆的意思就是上面的都比下面大,或者小。

举个例子,下图就是个最小堆,父节点都比子节点小。如果将其反过来,父节点都比子节点大,那就是最大堆。

如图,想象一下东西是怎么磊成堆的,就能理解这个名字的精妙了。

 

      1

    /   /

  2     7

 / /    / /

3  4  8  9

 

堆很容易就可以用数组表示,任意元素i,其子节点就是[2*i],[2*i+1],其父节点就是[j/2],写起来很简单吧,也很容易理解。

 

堆排序的思想就是利用堆的这种父子节点大小关系的特性,来降低比较次数。

想象一下单循环淘汰赛,比如说欧洲冠军杯。先捉对厮杀,再一层一层往上走。堆排序就是这么做的。第一次从N中选出冠军。然后将冠军拿掉,剩下的N-1再选,以此计算,直到剩最后一个时,全部排序也就完成了。

 

举个例子:数组为:2, 5, 3, 2, 3, 0, 8, 1

得到初始状态如下图:

       2

     /   /

    5     3

   / /     / /

  2  3  0  8

 /

1

 

 

选出第一个冠军:

 

       8

     /   /

    5     2

   / /     / /

  2  3  0  3

 /

1

 

 

 

将冠军移到最后,然后,图也就变成

 

 

       1

     /   /

    5     2

   / /     / /

  2  3  0  3

 

8

继续选冠军:

       5

     /   /

    1      3

   / /     / /

  2  3  0  2

 

8

再将冠军移到树的最后:

       2

     /   /

    1      3

   / /     / /

  2  3  0  5

 

8

继续选冠军:

       3

     /   /

    2      3

   / /     /

  2  1  0  5

 

8

再将冠军移到树的最后:

       0

     /   /

    2     3

   / /

  2  1  3  5

 

8

继续选冠军:

       3

     /   /

    2     0

   / /

  2  1  3  5

 

8

再将冠军移到树的最后:

       1

     /   /

    2     0

   /

  2  3  3  5

 

8

继续选冠军:

       2

     /   /

    1     0

   /

  2  3  3  5

 

8

再将冠军移到树的最后:

       2

     /   /

    1     0

 

  2  3  3  5

 

8

继续选冠军:

       2

     /   /

    1     0

 

  2  3  3  5

 

8

再将冠军移到树的最后:

       0

     /

    1     2

 

  2  3  3  5

 

8

继续选冠军:

       1

     /

    0     2

 

  2  3  3  5

 

8

再将冠军移到树的最后:

       0

 

    1     2

 

  2  3  3  5

 

8

搞定啦!
0, 1, 2, 3, 3, 5, 8
代码如下:
 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值