我---对‘数据结构’中‘排序’的理解 ---------3:选择排序--(二)堆排序

来源:互联网 发布:上海张江男 知乎 编辑:程序博客网 时间:2024/05/20 00:53

堆排序  

 

———————————————————引言——————————————————

树形选择排序 优化而来

锦标赛排序:

锦标赛排序,也称为树形选择排序(Tree Selection Sort),是一种按照锦标赛的思想进行选择排序的方法。

首先对n个记录进行两两比较,然后优胜者之间再进行两两比较,如此重复,直至选出最小关键字的记录为止。这个过程可以用一棵有n个叶子结点的完全二叉树表示。根节点中的关键字即为叶子结点中的最小关键字。在输出最小关键字之后,根据关系的可传递性,欲选出次小关键字,仅需将叶子结点中的最小关键字改为“最大值”,如∞,然后从该叶子结点开始,和其左(右)兄弟的关键字进行比较,修改从叶子结点到根的路径上各结点的关键字,则根结点的关键字即为次小关键字。

这种算法的缺点在于:辅助存储空间较多、最大值进行多余的比较。

为了弥补这些缺点,1964年,堆排序诞生。                                                                       此段摘自: http://roclinux.cn/?p=675

 

 

树形选择排序图示:

                                                                                                ------------图 《数据结构》(严蔚敏)

 


————————————————————————引言end—————————————————————————————


 

  • 第一部分:概念

 


 

1.堆

堆的定义如下:n个元素的序列{k1,k2,,...,kn}当且仅当满足下关系时,称之为堆。


  • ki <= k2i
  • ki <= k2i+1       (小顶堆)        或     


  • ki >= k2i
  • ki >= k2i+1       (大顶堆)  


(i = 1,2,...,[n/2])


若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。

由此,若序列{k1,k2,,...,kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。

例如,下列两个序列为堆,对应的完全二叉树如图

                                          




2.堆排序

以图(b)为例:

若在输出堆顶的最小值之后,使得剩余n-1个元素的序列重又建成一个堆,则得到n个元素中的次小值。如此反复执行,便能得到一个有序序列,这个过程称之为堆排序。

 

—————————————————————————————————————————————————————————

 

  • 第二部分 一点疑惑

 

a. 概念

刚 研究 堆排序 的时候,将【完全二叉树,堆】的概念无法联系到排序中,很混乱。


堆的定义是应堆排序而生的,堆的表现形式即为完全二叉树;


好了,再来看看"堆(Heap)"是个神马玩意儿?

其实,堆就是一颗完全二叉树,任意给定一个数组,我们就能将它构造成一颗完全二叉树,也就是创建一个“堆”

--ps:还好业内标准称它为一堆,而不是一坨 :)            

-----------http://www.cnblogs.com/yjmyzz/archive/2010/12/21/1913102.html

 


过程是这样的:(以对序列倒序排序为例)


1. 待排序的序列 {40,55,49,73,12,27,98,81,64,36}(一维数组)

2. 构造大顶堆(大顶堆,完全二叉树)


3. 由上图,得到新序列{98,81,49,73,36,27,40,55,64,12};(将大顶堆还原为一维数组)

4. 交换 98 和 12,得到新序列{12,81,49,73,36,27,40,55,64,98};(一维数组)

5. 对 去掉 98的 新序列{12,81,49,73,36,27,40,55,64}构造大顶堆 即重复2;(新一维数组继续构造大顶堆)

 

整个过程为下图:

 

 

 

b. 筛选

 

图中 “筛选”的过程,即是重新构造大顶堆的过程。(我们应将“筛选” 单独出来一个算法)

 

 

 

 

  • 第三部分:算法和源代码

算法如下:

 

 

 

 

实现代码如下:


 

  • 第四部分 各种网摘总结

 

1.这是一种思维方式很独特的排序方式,时间复杂度跟快速排序类似,也是跟二叉树有关,为O(Nlog2N),同样它也是一种不稳定的排序。

 

2.

  csdn有篇帖子是说"5000个数中找出10个最大的用哪种排序最快",答案是堆排序.

 
我看网上说:"直接选择排序中,为了从R[1..n]中选出关键字最小的记录,必须进行n-1次比较,然后在R[2..n]中选出关键字最小的记录,又需 要做n-2次比较。事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排 序时又重复执行了这些比较操作.堆排序可通过树形结构保存部分比较结果,可减少比较次数。".  

 

3.


 

原创粉丝点击