【问题标题】:What is the algorithmic complexity of this sorting function?这个排序函数的算法复杂度是多少?
【发布时间】:2013-01-04 14:24:16
【问题描述】:

我在玩乐高积木时设计了以下排序算法,其理念是始终将较小的部分堆叠在较大的部分之上,直到您遇到不适合堆栈两端的部分。

我最初的印象是它的最佳情况是 O(n),最坏情况是 O(n^2),因为它类似于链排序,但是我已经很久没有做算法分析了在大学里,我不知道它的平均行为是什么。看起来它应该比链排序的平均 O(n^2) 更好,但我不知道如何证明它或它是什么。

我的实现使用链表来允许在两端插入,但双端队列也可以。以下是 Python 代码,方便描述,但 C++ 版本效率更高。

import math

def merge(x, y):
    output = []
    xp = 0
    yp = 0
    if len(y) == 0 or len(x) == 0 or y[0] > x[-1]:
        return x + y
    elif x[0] > y[-1]:
        return y + x
    while xp < len(x) and yp < len(y):
        if x[xp] < y[yp]:
            output.append(x[xp])
            xp = xp + 1
        else:
            output.append(y[yp])
            yp = yp + 1
    if xp < len(x):
        output = output + x[xp:]
    elif yp < len(y):
        output = output + y[yp:]
    return output

def treeMerge(heads, accum):
    currHead = 0
    while heads[currHead] is not None:
        accum = merge(heads[currHead], accum)
        heads[currHead] = None
        currHead = currHead + 1
    heads[currHead] = accum
    return heads

def legoSort(input):
    heads = [None] * int(math.log(len(input), 2) + 1)
    accum = []
    for i in input:
        # can be <= for speed at the cost of sort stability
        if len(accum) == 0 or i < accum[0]: 
            accum.insert(0,i)
        elif i >= accum[-1]:
            accum.append(i)
        else:
            heads = treeMerge(heads, accum)
            accum = [i]
    for i in heads:
        if i is not None:
            accum = merge(accum, i)
    return accum

【问题讨论】:

    标签: python sorting complexity-theory


    【解决方案1】:

    看起来你得到了类似于 timsort 或 natural merge 的东西。

    【讨论】:

    • 是的,一个使用向前和向后运行的自然合并。
    【解决方案2】:

    研究用未知语言编写的未知代码是相当无聊的。您宁愿在分析结束时在这里http://en.wikipedia.org/wiki/Merge_sort 找到它

    【讨论】:

    • 它是 Python。 :/ 这根本不是一种未知语言。
    • 同意,尽管投票赞成,因为它绝对是合并排序的一种变体,而且他所指的变体似乎是你可能正在做的事情。他也可能在攻击你,因为 python 使用涉及合并排序的 Timsort。
    • 是的,我知道它是 Python。我的意思是这对我来说是未知的。这对我来说很难将程序转换为算法。
    • 我感觉不像是合并排序(当然,除了合并列表);它没有任何递归行为。我看到了与 timsort 的相似之处;谢谢你的提示。最大的不同是该算法的双端性允许提取反向运行(或更复杂的,像 5 6 4 7 3 8 2 9 1 被处理为运行),但驰骋过程在概念上看起来确实相似。
    • 嗯,看起来很相似,虽然没有递归。如果我错了,也许我应该删除答案。
    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-06
    • 2015-06-12
    • 1970-01-01
    相关资源
    最近更新 更多