基于比较的排序算法的最优下界为什么是O(nlogn)

发表于2013/12/21 16:15:50  1024人阅读

分类: Algorithm

1.决策二叉树

回答这个问题之前我们先来玩一个猜数字的游戏,我从1到8中挑一个数字出来让你来猜,每回合你都可以问我一个问题,我的回答“是”或“不是”(1或0),那么你至少需要几个回合才能保证猜出这个数字?比较符合这个游戏精神的玩法是从自己的幸运数字(比如我的是7)开始猜起,一个一个地问我“是不是X?”,可能你的运气足够好,一个回合就能够猜对,但是在最坏的情况下可能就需要8个回合,所以你的答案应该是“至少需要8个回合”(事实上你至少只需要一次就“有可能”猜出来,但为了“保证能”猜出来,你只好委曲求全地说8),换句话说这种猜法的最优下界是8。(平均性能是1×1/8+2×1/8+…+8×1/8=(1+…8)/8=4.5)

但因为你会二分,所以会这样问“是不是比4大?”……而且无论我挑出的数字是几,都只用3个回合。显然这是一种更佳的策略,那么它好在什么地方呢?

如果用信息论的思想来解释,这种猜法每一轮(提问并得到反馈)得到的信息量更大。因为在你不知道这个问题的答案时,我回答“是”和“不是”的概率是相同的(如果你不打开盖子,猫是死还是活的概率是相同的),因此每回合你所获取的信息量都是最大的(熵)。而第一种猜法,比方你第一次问我“是不是7?”,我回答“不是”的概率为“是”的概率的7倍(1/8:7/8),因此得到的信息量就少了。如果你问我“是不是42?”那么信息量就更少了(为0),因为我回答“是”的概率为0……相当于你这个问题白问了。

这就像一个未知的世界,一开始你对这个世界一无所知,然后你通过问我问题来获取一些信息,直到你所取得的信息量能够帮助你认清这个世界。

另一种更加形象的模型是决策树(如图),每一个决策都将引出两个结果,叶子节点代表数字已经猜出。二分思想的决策树十分平衡,因此每次猜测无论是对还是错都能将够将数字的范围缩小一半。最优下界即二叉树的深度,具有L片树叶的二叉树的深度至少是logL,所以logn是n个数字的最优下界。而下面那棵二叉树,虽然很有可能在在第一次分支处就使游戏终结,但是却有很大的概率会失败(需要接着往下猜),这个时候回过头来看刚刚的决策——仅仅将范围缩小了一点点。从直观上感觉这种方法也是比较冒风险的。

2.比较排序的决策树模型

绕了一个大圈子其实就是为了说比较排序的决策树模型。a1,a2,a3……an排序总共有n!总结果,(其中a1'<=a2'<=a3'……<=an')所占的概率是1/n!,每进行一次比较,就是在这n!种结果中进行二分,接着选择一个二分结果进行下一次二分,直到找到想要的排序。排序算法能不能自顶向下构造出一棵决策树?因为我们讨论的是基于输入元素的比较排序,每一次比较的返回不是0就是1,这恰好可以作为决策树的一个决策将一个事件分成两个分支。比如冒泡排序时通过比较a1和a2两个数的大小可以把序列分成a1,a2……an与a2,a1……an(气泡a2上升一个身位)两种不同的结果,因此比较排序也可以构造决策树。根节点代表原始序列a1,a2,a3……an,所有叶子节点都是这个序列的重排(共有n!个,其中有一个就是我们排序的结果a1',a2',a3'……an')。如果每次比较的结果都是等概率的话(恰好划分为概率空间相等的两个事件),那么二叉树就是高度平衡的,深度至少是log(n!)。又因为log(n!)的增长速度与 nlogn 相同,即 log(n!)=Θ(nlogn),这就是通用排序算法的最低时间复杂度O(nlogn)的依据。

-------------------------------------------------------------------------------------------
证明log(n!)=Θ(nlogn)等价于证明①、②

①log(n!)=O(nlogn)
显然n!<n^n,两边取对数就得到log(n!)<nlog(n)。

②log(n!)=Ω(nlogn)
n!=n(n-1)(n-2)(n-3)…1,把前n/2个因子(都大于n/2)全部缩小到n/2,后n/2个因子全部舍去,得
n!>(n/2)^(n/2)。两边取对数,log(n!)>(n/2)log(n/2),后者即Ω(nlogn)。

-------------------------------------------------------------------------------------------

为了理解O(nlogn)这个公式的含义,下面来看这样一道题:排序5个数至少需要几次比较?

用合并排序(merge sort,算法复杂度为O(nlogn))对3、2、5、1、4进行排序。下面给出了5个数合并排序的归并树,共需要4+2+1+1=8次比较。

[1][2][3][4][5]   
                     /              \
               [2][3][5]     [1][4]
                /      \           /   \
          [2][3]      5      1     4
            /    \
          3      2

那么,这是最优的吗?通过决策树模型,我们知道基于比较的排序算法的算法复杂度是log(n!),因此排序5个数所需要最小的比较次数应该是7次(log(5!)=log(120)≈6.91),而归并排序用了8次。

虽然log(n!)和nlogn的增长率相同,但在n比较小的时候,后者的值差不多是前者的两倍。(下表是这函数的增长规律,log(n!)比较难计算,用chromey calculator最多只能算到log(170!))。

n           2   3     4     5    10   20    30    50    100   150   170
log(n!)  1   3     5     7    22   61   108   214   525   873   1019
nlogn    2   5   11   12   33   86   147   282   664   1084  1260

如果我们用nlogn这个公式计算5数归并排序的算法复杂度,得到的结果应该是12,事实上只需要8次比较即可。原因是在用“递归树”(算法导论p22)计算merge sort的算法复杂度的时候,我们保守估计了每层的复杂度,n是已经是一个上界了,换句话说每层是O(n),有logn+1层,因此归并算法的最优下界是O(nlogn)。

实际的使用归并算法排n数的复杂度总是要低于nlogn(因为每层比较次数少于n)的,能否等于log(n!)(最优的下界)呢?不可能,反例就是n=5,(证明一个东西错误总是比证明它正确容易得多——Knuth),那么为什么不行呢?还是那个老问题,看它对于事件的划分。虽然我没有画出5数归并排序的决策树,但是从归并树上也可以看出问题出在“ [2][3][5](2次)”的这一步。这一步有两次比较:第一次比较2和5,较小的数字进入a[0];第二次将较大的那个数和3进行比较,较小的进入a[1],较大的进入a[2]。而在第一次比较时就出现了概率不均的场面,如果5<2将产生[5][2][3]这一种结果,反之将得到[2][5][3]和[2][3][5]两种结果,概率空间1:2!

下图给出了用7次排5数的决策树(如果对称则省去一支),可以看到每次划分都是十分均衡的。

划分的关键是第三、第四次比较,“a与b”和“c与d”的那比较肯定是等概率的,如果之后分别将e与a和b(或者c和d)比较,将会使两个分支出现一大一小的场面,在比较的初期,出现这种不平衡是致命的!一个分支可能提前“解放”,经过三两次二分就得到了结果,另一个分支的“责任”则突然变大,导致无法再指定次数内完成分解。

唯一的不均衡出现在第5层,因为15不能被2整除,所以7:8已经算得上是很不错的划分了。所以只有在n!=2^k时,才有可能出现一棵高度平衡的二叉树。

因此这个排序算法的最优下界好于merge sort,缺点是只能排5数,因此这个算法不是通用算法,而诸如归并、快排、堆排、希尔在内的最优下界为nlogn的算法都是通用的

转载~基于比较的排序算法的最优下界为什么是O(nlogn)的更多相关文章

  1. [ 转载 ] js十大排序算法:冒泡排序

    js十大排序算法:冒泡排序  http://www.cnblogs.com/beli/p/6297741.html

  2. 基于Qt5的排序算法简单可视化

    之前写了几个排序算法,然后看到别人将排序算法的过程可视化出来,所以就想尝试一下,然后就用Qt简单写了个界面,用QImage和QPainter来画图显示,代码比较简单. 我的想法是画图的时候,图像的X轴 ...

  3. 不基于比较的排序算法:Counting-sort和Radix-sort

  4. 排序算法之堆排序(Heapsort)解析

    一.堆排序的优缺点(pros and cons) (还是简单的说说这个,毕竟没有必要浪费时间去理解一个糟糕的的算法) 优点: 堆排序的效率与快排.归并相同,都达到了基于比较的排序算法效率的峰值(时间复 ...

  5. 常见排序算法总结分析之选择排序与归并排序-C#实现

    本篇文章对选择排序中的简单选择排序与堆排序,以及常用的归并排序做一个总结分析. 常见排序算法总结分析之交换排序与插入排序-C#实现是排序算法总结系列的首篇文章,包含了一些概念的介绍以及交换排序(冒泡与 ...

  6. 第32讲:List的基本操作实战与基于模式匹配的List排序算法实现

    今天来学习一下list的基本操作及基于模式匹配的排序操作 让我们从代码出发 val bigData = List("hadoop","spark") val d ...

  7. 【转载】常见十大经典排序算法及C语言实现【附动图图解】

    原文链接:https://www.cnblogs.com/onepixel/p/7674659.html 注意: 原文中的算法实现都是基于JS,本文全部修改为C实现,并且统一排序接口,另外增加了一些描 ...

  8. 十大经典排序算法(java实现、配图解,附源码)

    前言: 本文章主要是讲解我个人在学习Java开发环境的排序算法时做的一些准备,以及个人的心得体会,汇集成本篇文章,作为自己对排序算法理解的总结与笔记. 内容主要是关于十大经典排序算法的简介.原理.动静 ...

  9. <Data Structure and Algorithm>排序算法

    排序稳定:如果两个数相同,对他们进行的排序结果为他们的相对顺序不变.例如A={1,2,1,2,1}这里排序之后是A = {1,1,1,2,2} 稳定就是排序后第一个1就是排序前的第一个1,第二个1就是 ...

随机推荐

  1. chrome 切换到其他网络后重新加载网

    chrome 突然提示 “您与 www.google.com 之间的安全连接目前正受到干扰.  请等待几分钟后再尝试重新加载网页,或在切换到其他网络后重新加载网” 查看证书发现 已经过期 解决:同步下 ...

  2. 《Cracking the Coding Interview》——第7章:数学和概率论——题目5

    2014-03-20 02:20 题目:给定二维平面上两个正方形,用一条直线将俩方块划分成面积相等的两部分. 解法:穿过对称中心的线会将面积等分,所以连接两个中心即可.如果两个中心恰好重合,那么任意穿 ...

  3. 二分法求函数值的Pascal实现

    用二分法求在(a,b)上单调的函数近似值   第八行的表达式可更改,第三行的kexi决定的精度,小数值计算可将第五行的extended更为real或double PROGRAM EQUANTION ( ...

  4. loadrunner检查点设置失败,日志中SaveCount无法被正常统计出来

    在脚本正确的情况下的web_reg_find检查点检查失败,SaveCount无法被正常统计出来. 在检查项Text为中文的情况下, ******(我是被录制下来的代码) web_reg_find(& ...

  5. python学习笔记-基础

    1.大小写敏感 2. print (n,f,s1,s2,s3,s4,sep='\n')  -- 换行输出  seq='\n' print ('n=%d'%n,'f=%f'%f,'s1=%s'%s1,' ...

  6. 【转载】Unity插件研究院之自动保存场景

    原文: http://wiki.unity3d.com/index.php?title=AutoSave  最近发现Unity老有自动崩溃的BUG. 每次崩溃的时候由于项目没有保存所以Hierarch ...

  7. 牛客网暑期ACM多校训练营(第一场):J-Different Integers(分开区间不同数+树状数组)

    链接:J-Different Integers 题意:给出序列a1, a2, ..., an和区间(l1, r1), (l2, r2), ..., (lq, rq),对每个区间求集合{a1, a2, ...

  8. Nova 如何统计 OpenStack 资源

    1.云计算的本质在于将硬件资源软件化,以达到快速按需交付的效果,最基本的计算.存储和网络基础元素并没有因此改变.就计算而言,CPU.RAM 和 DISK等依旧是必不可少的核心资源. 从源代码和数据库相 ...

  9. css深入理解vertical-align

    第一讲:vertical-align家族基本认识 了解vertical-align支持的属性值以及组成 属性: 1.inherit 2.线类 baseline,top,middle,bottom 3. ...

  10. HTML5应用:setCustomValidity(message)接口

    本文转自http://tid.tenpay.com/?p=3592 HTML5表单验证给前端人员带来了便利,但是在用户体验上存在一些缺陷,默认的提示对用户很不友好,无法准确的获取想要的信息.好在大牛们 ...