我遇到了一个问题,我只需要一个方向的提示/点(不要求答案)
该问题要求分治算法的细节,该算法给出几乎排序的序列,在时间O(n)中产生正确的顺序。
几乎排序的意思是给定列表
x_1,x_2,.... x_n
如果排序列表由
表示y_1,y_2,... y_n
并且对于每个i,j< = n这个属性都得到尊重:
x_i == y_j&& | I-J | < = root(n)
我唯一想到的就是将列表分成每个级别的根(n)组(这将导致它们在第一次拆分时最多为根(n)),但我不是太确定从哪里开始,因为你需要在重新加载时一次加入root(n)元素。
我还发现递归复杂度方程是:
T(n)= root(n)* T(n / root(n))+ d * root(n)
其中master's theorem
可以证明是O(n)时间。
所以看起来我似乎正处于分裂的正确轨道上,我只是不确定它是否应该以特殊的方式拆分或者以某种方式比较什么。
编辑:据说这是正确答案。
我们的算法如下:如果n> 1,然后我们递归地对序列的两个(近似)半部分中的每一个进行排序;现在所有的元素都处于正确的位置,除了可能位于中间√n位置的元素(你知道为什么这是真的吗?);所以我们现在合并这些位置的元素。如果我们让T(n)是用于排序nelements的时间,那么对于n> 1我们有
T(n)≤2T(⌈n=2⌉)+ c *√n
因为√(n)= n .5 和.5 < 1 = log 2 2,划分和征服复发的主定理告诉我们T(n)∈O(n)。
我不确定我是否同意,因为排序两半的时间将是O( n / 2 * log( n / 2 ))其中O(n * logn)最终合并为O(√n*√n),O(n)给出总计O(n) * logn + n) - &gt;为O(n * logn)时间
答案 0 :(得分:1)
我认为基于比较的排序不可能在O(n)
中进行。
考虑简化的问题,其中排序的数组被分成√n桶,并且每个桶内的元素被洗牌。满足每个元素必须不超过其最终位置的√n位置的条件。
要解决此问题,您必须对每个桶进行排序。使用任何O(n*logn)
排序,您将得到√n*(√n*log√n)。这是(1/2)* n * logn,仍为O(n*logn)
。
由于此简化问题只能在O(n*logn)
中解决,因此我得出结论,使用基于比较的排序无法在O(n)
中解决原始问题。
例如,如果您知道所有元素都是某个范围内的整数,则不再局限于基于比较的排序,并且可以使用非基于比较的O(n)
来解决问题排序,例如pigeon sort。
答案 1 :(得分:1)
这样的算法可用于在O(r * r)时间内对r项列表进行排序,只需通过连接列表(并在必要时装饰元素)。但是,众所周知,对于n = r * r,你不能做得比O(r * r * ln(r))或O(n * ln(n))更好。
我想原来的问题是一个不同的问题,或者在计算复杂性时向你提出原始问题的人犯了一个错误。例如,假设当列表分成两半时,两个部分仍然几乎排序。 (有很多方法可以用这种方式拆分列表,比如取每一个元素,但不是列表的每个分区都有这个属性。)
答案 2 :(得分:0)
第一条线索:T(n)= root(n)* T(n / root(n))+ d * root(n)不正确。由于它是一个递归函数,因此对于T(root(n))不是这样。