2017-08-26 68 views
2

双端选择排序,即交换最小和最大的排序,声称更快是一个普通的选择排序,即使认为比较的数量是相同的。我明白,它摆脱了一些循环,但如果比较的数量保持不变,它们如何更快?算法 - 双端选择排序真的比单端排序更快吗?

在此先感谢

+0

'更快'取决于*机器*。尽管比较次数相同并不成立:比较(输入)值对,只有非更大值是最小值的候选值,非最小值是最大值。 – greybeard

+2

你能具体说明你的意思吗?这两种算法在所有情况下执行完全相同数量的比较是不太可能的。现在很难回答这个问题,因为基本上你要求证明或驳斥你实际上没有描述的第三方声明。这也有点猜测什么是“双重选择排序” - 你有链接到你正在讨论的实现吗? –

+0

我在我的答案中展示了一个实际演示和数学分析,双端选择排序执行比常规选择排序更多的比较。所以这个问题的假设,他们执行相同数量的比较是不正确的。 –

回答

0

这里的选择排序和双端选择那种指望执行的比较的实现。

如果运行它,您会看到双端选择排序总是执行更多比常规选择排序。

import random 

def selsort(xs): 
    N = len(xs) 
    comparisons = 0 
    for i in xrange(N): 
     m = i 
     for j in xrange(i+1, N): 
      comparisons += 1 
      if xs[j] < xs[m]: m = j 
     xs[i], xs[m] = xs[m], xs[i] 
    return comparisons 

def deselsort(xs): 
    N = len(xs) 
    comparisons = 0 
    for i in xrange(N//2): 
     M = m = i 
     for j in xrange(i+1, N-i): 
      comparisons += 2 
      if xs[j] < xs[m]: m = j 
      if xs[j] >= xs[M]: M = j 
     xs[i], xs[m] = xs[m], xs[i] 
     if M == i: M = m 
     xs[N-i-1], xs[M] = xs[M], xs[N-i-1] 
    return comparisons 


for rr in xrange(1, 30): 
    xs = range(rr) 
    random.shuffle(xs) 
    xs0 = xs[:] 
    xs1 = xs[:] 
    print len(xs), selsort(xs0), deselsort(xs1) 
    assert xs0 == sorted(xs0), xs0 
    assert xs1 == sorted(xs1), xs1 

这是因为常规选择排序是比较的数量:

(n-1) + (n-2) + ... + 1 = n(n-1)/2 

对于双端选择排序,比较的数量是(奇数N - 偶的情况是相似的)

2(n-1) + 2(n-3) + 2(n-5) + ... + 2 
= (n-1)+(n-2)+1 + (n-3)+(n-4)+1 + ... 2+1+1 
= ((n-1) + (n-2) + ... + 1) + (n-1)/2 
= n(n-1)/2 + (n-1)/2 

(在这里,我重写每学期2(n-i)(n-i) + (n-i-1) + 1

+0

这是否意味着双倍结束选择排序较慢? – qunayu

+0

在内部循环中,如果第一个结果为假,则只需进行第二次比较。这样可以节省一些比较。 – Selindek

+0

好吧,不完全相同的数量,但如果我们将相互比较的数量除以1,那么限制将会是1.所以它就像渐近地相同或不相似? – maraca