如果您可以在 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 个标准进行排序?