排序大集锦(三):基于随机访问下标的排序

基于数组中元素之间的比较的排序算法被称为比较排序。其基本思想非常简单,假定在待排序数组a[0..n-1]中存在任意两个元素a[i]及a[j],若a[i]≥a[j],那么在最终的序列中a[i]必定在a[j]之后。对于这类算法,实际可以通过决策树来简单描述其工作过程,考虑一个具有三个元素的数组a[0..2],比较过程如下图所示:


如上图所示,在由决策树所得到的解空间中总共有3!=6种结果。因为根节点到每个叶节点的一条路径表示一种排序方式,因此路径的长度等价于比较次数,且最坏情况下的运行时间为整棵决策树的高度。现考虑一个具有n个元素的数组a[0..n-1],其高度为h,总共存在n!种不同的排序路径,又因为排序路径的长度不同,因此决策树中叶子节点的总数必定小于具有同样高度h的完全二叉树中叶子节点的总数。由于在高度为h的完全二叉树中叶子节点个数为2h,我们有n!≤2h,据斯特林近似公式得到h=Ω(n㏒n),所以任何基于比较的排序算法在最坏情况下的运行时间都渐进等同于Ω(n㏒n)。

既然有比较排序,那么自然会有非比较排序。在正式介绍非比较排序算法前,我们先来更加深入的思考一下比较排序的基本思想,由于其是通过数组中元素之间的两两比较从而得到最终的结果序列,也就是说某个元素在寻找序列中的正确位置时是以其他元素作为所选择的参照点,那么是否可以通过选择另外一种参考系来对数组进行排序呢?如果这是可能的,那么所选定的参考系又该满足什么样的特点?首先来看下面这张图:

可以根据上图设想存在如下场景:现有一老师要为一群学生按身高进行排列。老师可以采取以下两种策略:①让同学们两两之间相互比较从而确定自己应该站立的位置,老师只发号施令。②老师充分发挥主观能动性,首先安排另外一块场地并制定如下规则:1号位置站的同学身高为160cm,2号位置站的同学身高为161cm……依此类推。最后同学们根据自己的身高找到对应的位置。对于策略①也就是我们之前所说的比较排序,对于策略②也就是本文所要实现的另外一种排序方式,而神奇的参考系f就是老师所制定的规则。

这里我们更加深入的思考一下策略②所带来的问题:

  • 老师应该大致了解同学们身高的范围,否则他就不能合理的安排1号位置站的同学的身高。
  • 其次一个位置上可能站着0个,1个或者多个同学。
  • 最重要的一点是,同学们必须要知道自己的身高,否则就没法对号入座。


根据上例,这种“绝对排序”所需要满足的特点总结如下:

  1. 首先我们必须知道元素的大致范围,否则就没有办法给待排序元素安排合理的空间。
  2. 其次非比较排序必须以有序实体作为参考对象。
  3. 由于非比较排序并不两两比较,那么在原数组中必不发生交换操作。


计数排序
根据以上分析,观察到数组是以基址加偏移的方式引用的,而偏移量本身就是一种有序的客观存在实体,所以数组的随机访问下标可被作为参考对象。综上可得:

CNTSORT(source, dest, size)  /* argument 'size' is equal to the length of array */
assume r which is excluded as the range of the element in array
according to the assumption, we allocate appropriate memory space sizeof r for the array
/* what we have allocated named 'temp' and we initialize all of them with zero */
for i←0 to size-1
  do temp[source[i]]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值