`

为什么说任何基于比较的算法将 5 个元素排序都需要 7 次?

 
阅读更多

排序算法对结果的唯一要求就是操作数满足全序关系

  1. 如果 a≤b 并且 b≤c 那么 a≤c(传递性)。
  2. 对于 a 或 b,要不 a≤b,要不 b≤a(完全性)。

这个问题可以用信息论来回答。

我从 1 到 5 中挑一个数字出来让你来猜,每回合你都可以问我一个问题,我的回答“是”或“不是”(1 或 0),那么你至少需要几个回合才能保证猜出这个数字?

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

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

英文版维基百科词条有个大致的解释:Comparison_sort, 最少次数为 log(5!) = 6.91,取整的话,就是 7。

决策树如下:

比较排序决策树

如果我们用归并排序的话,比较次数是O(nlogn),因为归并排序是 全局最优解,但是在局部,归并并不都保证是最优的。

附一张快速排序的 gif 图:

快速排序

相关阅读:

面试算法有必要吗?

50
9
分享到:
评论
12 楼 haiyupeter 2013-04-23  
牛逼的gif图片
11 楼 tidelee 2013-04-23  
只为GIF
10 楼 venrains 2013-04-22  
taolei0628 写道
这个不难理解吧。一次比较只能识别两种状态。6次比较最多识别2^6=64种状态。
5个元素有120种排列,当然至少需要7次比较(2^7=128)才能把所有排列(状态)正确识别。

9 楼 justjavac 2013-04-22  
taolei0628 写道
这个不难理解吧。一次比较只能识别两种状态。6次比较最多识别2^6=64种状态。
5个元素有120种排列,当然至少需要7次比较(2^7=128)才能把所有排列(状态)正确识别。

8 楼 taolei0628 2013-04-22  
这个不难理解吧。一次比较只能识别两种状态。6次比较最多识别2^6=64种状态。
5个元素有120种排列,当然至少需要7次比较(2^7=128)才能把所有排列(状态)正确识别。
7 楼 wusuobuai 2013-04-22  
光看gif图就牛啊
6 楼 leaow567 2013-04-22  
哎~~老忘
5 楼 wupuyuan 2013-04-21  
只为gif图顶下。
4 楼 elan1986 2013-04-19  
3 楼 nodejs 2013-04-19  
coffeescript 写道
学习了。有个问题楼主:所有的比较排序算法应该都达不到 7 次吧?

手动排序。呵呵。
2 楼 coffeescript 2013-04-19  
学习了。有个问题楼主:所有的比较排序算法应该都达不到 7 次吧?
1 楼 artdialog 2013-04-19  
配图很好,一目了然。

相关推荐

    基于Qt5-实现九大排序算法的代码汇总

    通过选取一个“基准”元素,将序列划分为两部分,使得一部分的所有元素都小于另一部分,然后递归地对这两部分进行排序。快速排序的平均时间复杂度为O(n log n),但在最坏情况下(输入已排序或反向排序)为O(n^2)。 ...

    浅析基于C语言的常用排序算法比较.pdf

    选择排序算法是基于C语言实现的一种基础排序算法,其基本思想是:首先从待排序序列中选出最小(或最大)的一个元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(或最大)元素,以此类推,...

    基于mfc的内排序算法动态演示

    这个项目"基于MFC的内排序算法动态演示"是一个教学工具,它通过可视化的方式,帮助用户理解并比较多种内排序算法的执行过程。 **内排序算法** 内排序是指数据记录在内存中进行排序,包括但不限于以下几种常见算法...

    基于FPGA的并行全比较排序算法.pdf

    在深入分析这篇标题为“基于FPGA的并行全比较排序算法”的文章之前,先明确几个关键点:FPGA(Field-Programmable Gate Array,现场可编程门阵列),并行处理和排序算法。FPGA是一种可以通过编程来配置的集成电路,...

    C语言数据结构内部排序算法及比较

    7. **希尔排序**:改进的插入排序,通过增量序列将元素分组进行插入排序,最后进行一次全距为1的插入排序。时间复杂度在最好、最坏和平均情况下都优于简单的插入排序。 8. **计数排序**、**桶排序**和**基数排序**...

    c++各种的排序算法

    它的基本思想是采用分治法,选取一个基准元素,将数组分为两部分,一部分所有元素都小于基准,另一部分所有元素都大于基准,然后递归地对这两部分进行快速排序。这种算法在平均情况下的时间复杂度为O(n log n),但在...

    【排序结构5】 基于比较的内部排序总结

    【排序结构5】基于比较的内部排序总结 在计算机科学中,排序是将一组数据按照特定顺序排列的过程。内部排序,或称为内存排序,是指数据记录在内存中进行的排序,与外部排序(数据量太大无法全部装入内存)相对。本...

    排序算法的比较 10 种排序算法的代码都有 冒泡比较快速等等

    它的主要思想是重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 2. **快速排序**:由C.A.R. ...

    各种排序算法比较

    - **原理**:重复走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复进行的,直到没有再需要交换,也就是说该数列已经排序完成。 - **时间复杂度**:最好情况O(n),...

    常用排序算法java演示

    7. **计数排序(Counting Sort)、桶排序(Bucket Sort)和基数排序(Radix Sort)**:这三种排序算法属于非比较型排序,不依赖于元素间的比较,而是基于特定的特性,如元素的范围、分布等。Java中实现这类排序通常...

    课程设计 内部排序算法比较

    冒泡排序是一种简单的排序算法,它重复地遍历待排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 - **比较次数**...

    内部排序算法比较

    6. **堆排序**:利用堆这种数据结构,将待排序的序列构造成一个大顶堆(或小顶堆),然后将堆顶元素与末尾元素交换,调整剩下的元素为新的堆,重复此过程。 **二、实验设计** 实验中,使用C++语言编程实现这些排序...

    基于java语言十大经典排序算法

    计数排序不是基于比较的排序算法,它通过统计每个元素出现的次数,然后根据计数结果直接确定元素的最终位置。适用于非负整数排序,且范围不大的场景。 9. **桶排序(Bucket Sort)** 桶排序将元素分布到有限数量的...

    基于C语言的排序算法

    冒泡排序是最简单的排序算法之一,通过重复遍历待排序的数列,比较相邻元素并根据需要交换位置来实现排序。较大的元素逐渐“浮”到数列的顶端,就像水底下的气泡上升一样。虽然效率较低,但其逻辑简单,适合教学和...

    各种排序算法比较(java实现)

    合并排序是一种基于分治策略的排序算法,它将大问题分解为小问题来解决。首先将数组分为两个相等或近乎相等的部分,然后对每一部分递归地进行排序,最后将结果合并。这种算法的时间复杂度为O(n log n),稳定性好,...

    C语言常见排序算法及比较

    它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 **算法步骤**: 1. 比较相邻的元素。如果第一...

    5大排序算法

    选取一个“基准”元素,将数组分为两部分:一部分所有元素都小于基准,另一部分所有元素都大于基准,然后递归地对这两部分进行快速排序。快速排序的平均时间复杂度为O(n log n),最坏情况下(已排序或逆序)为O(n^2)...

    7大排序算法实现程序(快速排序,冒泡排序,选择排序,归并排序,插入排序,希尔排序,堆排序)

    首先构造一个大顶堆(或小顶堆),然后将堆顶元素与末尾元素交换,接着对剩余元素重新调整为堆,重复此过程,直到所有元素都被排序。 这七种排序算法各有优缺点,适用场景不同。快速排序通常最快,但最坏情况下性能...

    排序算法 各种算法的综合

    在最坏的情况下,冒泡排序需要进行N(N-1)/2次比较和交换,其时间复杂度为O(N²)。 2. **高级排序算法**:这部分通常涉及如快速排序或归并排序等更高效的算法,它们的时间复杂度为O(Log2(N))。这些算法利用分治策略...

Global site tag (gtag.js) - Google Analytics