如果您可以在 7 次比较中对 5 个数字进行排序,那么如何在 10 次比较中对 6 个数字进行排序?

Posted

技术标签:

【中文标题】如果您可以在 7 次比较中对 5 个数字进行排序,那么如何在 10 次比较中对 6 个数字进行排序?【英文标题】:if you can sort 5 numbers in 7 comparisons, how to sort 6 numbers in 10 comparisons? 【发布时间】:2011-05-16 19:40:19 【问题描述】:

还有一个问题是在 7 个比较中对 5 个数字进行排序:

Sorting an array with minimal number of comparisons

我的问题是在 10 次比较中对 6 个数字进行排序。

【问题讨论】:

考虑到您链接的问题的第一条评论,我原以为 6 个数字只需要 10 次比较 (6! = 720, 2 ** 10 = 1024) 是的,我注意到了,我会编辑问题。感谢您的提示 最后我们应该在 10(问题标题)或 13(问题正文)中进行? 【参考方案1】:

你可以在 12简单

用 7 个比较对前 5 个数字进行排序 将最终数字与前 5 个中的每一个进行比较,以确定其位置

当然,您可以比使用二分搜索做得更好...将最终数字与 5 的中间值进行比较,然后根据比较的结果与前两个或后两个进行比较。这应该最多进行 10 次比较。

【讨论】:

***.com/questions/2786899/…【参考方案2】:

做到这一点的最快方法(尽可能少的平均比较次数等于理论值)是:

c1 -→ o  | 3/10 comparisons
c2 -→ o
o -→ o

然后比较两个更大的数(c1 和 c2)我们有

o -→ c1

o -→ o -→ c2 | 4/10 comparisons
 ↘
   ↘o

然后我们比较 "c1" 和 "c2" 并得到两个可能的变体(第一个如果 c1 > c2,否则第二个)

A)Worse(26/45 of all cases)  B)Better(19/45)   | 5/10 comparisons

o -→ c1 -↘                             b-↘
           ↘                               ↘
  o -→ c2 -→ o                o -→ c1-→ c2-→ c3
   ↘                           ↘  
     ↘o                          ↘a

A) 在第一种情况下,我们的下一步将是比较“c1”和“c2”之后我们可以得到 A1) if c1>c2 else A2)

A1)                       A2)                 | 6/10
       o↘                 c1-→ c2 -→ o -→ o
          ↘                        ↗
 o -→ c1-→ c2 -→ c3              a -→ b
  ↘
    ↘a

A1) 我们按照序列 c1;c2;c3 对“a”进行排序,从与 c2 的比较开始,然后我们得到

A1.1)                     A1.2)               | 8/10
       a↘                            a↘
          ↘                             ↘
 c1-→ c2-→ o -→ o -→ o     c1-→ c2-→ c3-→ o -→ o 

A1)然后我们只需要在序列 c1;c2 或 c1;c2;c3 中对“a”进行排序(!) A1.1 和 A1.2 情况,比较中的“c2” 1-2 (A1) 或 2 (A2) 比较。

A2) 我们在 c1;c2 中排序“a”总是从与 c1 比较开始,然后我们在比“a”更小的元素序列中排序“b”,从与任何元素比较开始(如果有是 2) , 2nd (如果有 3 个), 2nd 或 3rd 中的任何一个(如果该序列中有 4 个元素)

B) 和上面一样,我们对序列 c1;c2;c3 中的“a”进行排序,从与 c2 的比较开始,然后我们在小于 c3 的元素序列中对“b”进行排序,从比较开始c2(如果有 3 个元素)或到 c2 或 c3(如果有 4 个元素)。这将进行 3-4 次比较。你也可以反之以“b”开头,结果不会改变。

该算法总共在 19/45 的情况下对 9 次比较中的 6 个数字进行排序,并且 在 26/45 的情况下进行了 10 次比较。

理论分钟

6!=720, 2^9=512,这意味着经过 9 次比较后,我们可以得到 512 个不同的结果,因此对于其中的 304 个(304 是 512 - 2*(720-512)),我们可以说“仅此而已,我们肯定知道顺序”,但是对于剩下的 208 个,我们需要再进行一次比较,以将它们与具有相同比较结果的 208 个另一种处置区分开来。 304/720 = 19/45; 208*2 / 720 = 26/45 ~ 0.578 所以最好的算法平均会有 9.578 次比较。 还有另一种选择:在 7 次比较中对 5 进行排序,然后在 3 次比较中对第 6 个元素进行排序,但是由于“7 中 5”的最佳算法是在 1/15 的情况下在 6 次比较中排序,“10 中的 6”算法将在 8 中排序1/45 例比较(16/45 例 9 次比较,28/45 例 10 次比较)导致平均 9.6 次比较。

【讨论】:

这个答案很棒。这里还有一些数字:对[0, 1, 2, 3, 4, 5] 的每个排列进行排序需要与 Ford-Johnson 算法(此处描述的算法)进行 6912 次比较,而与 Jon Skeet 描述的算法进行比较需要 6960 次。【参考方案3】:

我相信你可以做得比 13 更好,只是根据 O(n log n) 增长的原则。

基本方法是您设计一个决策树来确定您正在处理的排列,但对实际值不敏感。但是假设需要对可能的决策树进行详尽搜索才能找到最佳决策树,您需要注意,随着项目数量的增加,要考虑的决策树的数量非常会迅速增加。以指数方式猜测,虽然我没有检查过这个猜测 - 它甚至可能比这更糟。

你可以通过硬编码测试一个常见的排序算法——而不是像冒泡排序甚至(我怀疑)快速排序这样的 O(n^2) 算法来完成比 13 更好的测试。

基本上,我认为这个想法比它的价值更麻烦。五可能是硬编码最优排序的实际限制。任何更大的东西 - 只需使用标准排序算法。虽然我敢打赌,无论如何都会有人用实现来回答。

【讨论】:

谢谢。请注意,我将问题编辑为 10 个比较而不是 13 @Ali - 我认为 Jon Skeet 值得接受这个。我讨厌拒绝代表,而且我知道他并不完全需要,但他的回答仍然是一个实际的答案,而我的答案更多的是相关的非答案。

以上是关于如果您可以在 7 次比较中对 5 个数字进行排序,那么如何在 10 次比较中对 6 个数字进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

您如何在 LibreOffice Calc 中对超过 3 个标准进行排序?

如何在Java中对HashMap进行排序[重复]

剑指offer-最小的K个数

一个java问题,随机输入一组数字,从小到大排列,然后表示它是第几次输入的数字(问题在这),真心求助。

排序之冒泡排序

谜题:在一次解析中对包含 0 和 1 的数组进行排序。