我制作了一个排序算法,但后来我想也许我刚刚彻底改造了快速排序。
然而我听说快速排序是O(N ^ 2)最坏的情况;我认为我的算法应该只是O(NLogN)最坏的情况。
这与quicksort相同吗?
该算法通过交换值来工作,以便将小于中值的所有值移动到数组的左侧。然后它在每一方递归地工作。
算法从i = 0开始,j = n-1
i和j在列表[i]和列表[j]之间相互移动,如有必要,可以互换。
以下是递归之前第一次迭代的一些代码:
_list = [1,-4,2,-5,3,-6]
def in_place(_list,i,j,median):
while i<j:
a,b = _list[i],_list[j]
if (a<median and b>=median):
i+=1
j-=1
elif (a>=median and b<median):
_list[i],_list[j]=b,a
i+=1
j-=1
elif a<median:
i+=1
else:
j-=1
print "changed to ", _list
def get_median(_list):
#approximate median in O(N) with O(1) space
return -4
median = get_median(_list)
in_place(_list,0,len(_list)-1,median)
"""
changed1 to [-6, -5, 2, -4, 3, 1]
"""
答案 0 :(得分:4)
http://en.wikipedia.org/wiki/Quicksort#Selection-based_pivoting
相反,一旦我们知道最坏情况的O(n)选择算法是 可用,我们可以用它来找到理想的枢轴(中位数) 快速排序的步骤,生成具有最坏情况O(n log n)的变体 运行时间。然而,在实际实现中,这种变体是 平均来说要慢得多。
另一种变体是选择中位数中位数作为支点 元素而不是中值本身用于分割元素。 同时保持渐近最优的运行时间复杂度 O(n log n)(通过防止最坏情况分区),它也是 比选择中位数作为支点的变量要快得多。
答案 1 :(得分:2)
对于初学者,我假设还没有显示其他代码,因为我很确定你自己展示的代码不起作用。
我很抱歉偷你的火,但我担心你做的代码似乎是Quicksort,不仅如此,但代码似乎可能会遇到一些错误。
考虑排序相同元素列表的情况。您的_in_place
方法似乎是Quicksort中传统上称为分区的方法,不会正确移动任何元素,但最后j
和i
似乎只反映了列表一个包含整个列表的分区,在这种情况下,您将永远在整个列表中再次递归。我的猜测是,如上所述,你不会从它返回任何东西,或者似乎实际上完全排序在任何地方,所以我猜测如何使用它。
我担心使用Quicksort的实际中位数不仅是一般情况下可能相当慢的策略,它也不能避免O(n ^ 2)最坏的情况,同样会提供相同元素的列表这是一个最坏的情况。但是,我认为具有这种中值选择算法的三分区Quicksort将保证O(n * log n)时间。尽管如此,这是枢轴选择的已知选项,而不是新算法。
简而言之,这似乎是一个不完整且可能有错误的Quicksort,并且没有三向分区,使用中位数并不能保证你O(n * log n)。但是,我确实觉得这是一件好事,值得祝贺你确实想到了自己使用中位数的想法 - 即使之前已被别人想到过。