做到这一点的最快方法(尽可能少的平均比较次数等于理论值)是:
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 次比较。