如果你有5个不同的数字,你需要多少次比较才能使用合并排序对它进行排序?
答案 0 :(得分:6)
什么阻止你编写合并排序,保持计数器中的比较数,并在[0,1,2,3,4]的所有排列上尝试?
答案 1 :(得分:4)
我觉得这个问题很有意思,所以我决定彻底探索它(在Python中进行一些实验)。
我从here下载了mergesort.py
并修改了它,为比较器函数添加了cmp
参数。然后:
import collections
import itertools
import mergesort
import sys
class CountingComparator(object):
def __init__(self):
self.count = 0
def __call__(self, a, b):
self.count += 1
return cmp(a, b)
ms_histo = collections.defaultdict(int)
for perm in itertools.permutations(range(int(sys.argv[1]))):
cc = CountingComparator()
lperm = list(perm)
mergesort.mergesort(lperm, cmp=cc)
ms_histo[cc.count] += 1
for c in sorted(ms_histo):
print "%d %2d" % (c, ms_histo[c])
得到的简单直方图(从长度4开始,就像我开发和调试它一样)是:
4 8
5 16
对于发布的问题,长度为5而不是4,我得到:
5 4
6 20
7 48
8 48
,长度为6(格式更广; - ):
7 8
8 56
9 176
10 288
11 192
最后,长度为7(甚至更宽的格式; - ):
9 16
10 128
11 480
12 1216
13 1920
14 1280
肯定会有一些完全规则的组合公式潜伏在这里,但我发现很难通过分析或粗略的数字来衡量它可能是什么。有人有建议吗?
答案 2 :(得分:3)
当合并排序两个长度为L1和L2的列表时,我认为最坏情况下的比较数是L1 + L2-1。
所以我猜答案是8。
这个数字序列导致上述情况: [2],[4],[1],[3],[5] - > [2,4],[1,3],[5] - > [2,4],[1,3,5] - > [1,2,3,4,5]
修改强>
这是一个天真的Erlang实现。基于此,对于1 ... 5的排列,比较次数为5,6,7或8。
-module(mergesort).
-compile(export_all).
test() ->
lists:sort([{sort(L),L} || L <- permutations()]).
sort([]) -> {0, []};
sort([_] = L) -> {0, L};
sort(L) ->
{L1, L2} = lists:split(length(L) div 2, L),
{C1, SL1} = sort(L1), {C2, SL2} = sort(L2),
{C3, RL} = merge(SL1, SL2, [], 0),
{C1+C2+C3, RL}.
merge([], L2, Merged, Comps) -> {Comps, Merged ++ L2};
merge(L1, [], Merged, Comps) -> {Comps, Merged ++ L1};
merge([H1|T1], [H2|_] = L2, Merged, Comps) when H1 < H2 -> merge(T1, L2, Merged ++[H1], Comps + 1);
merge(L1, [H2|T2], Merged, Comps) -> merge(L1, T2, Merged ++[H2], Comps + 1).
permutations() ->
L = lists:seq(1,5),
[[A,B,C,D,E] || A <- L, B <- L, C <- L, D <- L, E <- L, A =/= B, A =/= C, A =/= D, A =/= E, B =/= C, B =/= D, B =/= E, C =/= D, C =/= E, D =/= E].
答案 3 :(得分:2)
答案 4 :(得分:1)
根据Wikipedia:在最坏的情况下,合并排序进行的比较量等于或略小于(n⌈lgn⌉ - 2 ^⌈lgn⌉+ 1)
答案 5 :(得分:0)
对于仅排序的五个不同数字,您可以拥有的最大比较数为8,最小比较数为7.这就是原因: -
假设数组是a,b,c,d,e
递归地划分:a,b,c和d,e
递归地划分:a,b&amp; c和d&amp; e
递归划分:a&amp; b&amp; c和d&amp; e
现在,合并需要进行比较 -
a&amp; b:形成a,b的一个比较
a,b&amp; c:两次比较形成a,b,c
d&amp; e:形成d,e
的一个比较a,b,c和d,e:最坏情况下的四次比较或三次比较id d是形成a,b,c,d,e的数组的最大元素
因此,在最坏情况下,比较总数将为8,在最佳情况下为7。