Algorithm 分治算法对列表进行排序,其中每个元素的根(n)远离其排序位置

Algorithm 分治算法对列表进行排序,其中每个元素的根(n)远离其排序位置,algorithm,divide-and-conquer,Algorithm,Divide And Conquer,我被一个问题困住了,我只需要一个大致方向的提示/要点(不是问答案) 该问题询问了分治算法的详细信息,该算法给定一个几乎已排序的序列,在时间O(n)中生成正确的顺序 他们所说的几乎排序是指给定列表 x_1,x_2。。。。x_n 如果排序列表由 y_1,y_2。。。是的 对于每一个i,j1,我们递归地对序列的两个(近似)一半进行排序;现在所有的元素都在正确的位置,除了可能在√中间的n个位置(你知道为什么这是真的吗?);现在我们合并这些位置的元素。如果我们让T(n)为元素排序所用的时间,那么对于n>1

我被一个问题困住了,我只需要一个大致方向的提示/要点(不是问答案)

该问题询问了分治算法的详细信息,该算法给定一个几乎已排序的序列,在时间O(n)中生成正确的顺序

他们所说的几乎排序是指给定列表

x_1,x_2。。。。x_n

如果排序列表由

y_1,y_2。。。是的

对于每一个i,j1,我们递归地对序列的两个(近似)一半进行排序;现在所有的元素都在正确的位置,除了可能在√中间的n个位置(你知道为什么这是真的吗?);现在我们合并这些位置的元素。如果我们让T(n)为元素排序所用的时间,那么对于n>1,我们有

T(n)≤2T(⌈n=2⌉) +c*√n

自√(n) =n.5和.5<1=log22,分治循环的主定理告诉我们t(n)∈O(n)


我不确定我是否同意,因为对两半进行排序的时间是O(n⁄2*log(n⁄2)),结果是O(n*logn),最终合并是O(√n*√n) 第一个线索:T(n)=root(n)*T(n/root(n))+d*root(n)是不正确的。因为它是一个递归函数,所以对于T(root(n)),它是不正确的。

我认为基于比较的排序不可能在
O(n)
中实现它

考虑一个简化问题,其中排序的数组被划分为√n个bucket,每个bucket中的元素被洗牌。每个元素不得超过√从其最终位置算起的n个位置是满意的

要解决这个问题,您必须对每个bucket进行排序。使用任意
O(n*logn)
排序√n*(√n*log√n) 。这是(1/2)*n*logn,仍然是
O(n*logn)

由于这个简化的问题只能在
O(n*logn)
中解决,因此我得出结论,使用基于比较的排序来解决
O(n)
中的原始问题是不可能的


例如,如果您知道所有元素都是某个范围内的整数,那么您就不再局限于基于比较的排序,并且可以使用非基于比较的排序来解决
O(n)
中的问题,例如。

这样的算法可以用于对O(r*r)中r个项目的r个列表进行排序时间,只需将列表具体化(并在必要时修饰元素)。然而,我们知道,对于n=r*r,没有比O(r*r*ln(r))或O(n*ln(n))更好的了


我猜要么原始问题有点不同,要么给你原始问题的人在计算复杂性时犯了一个错误。比如,假设当列表被分成两半时,两部分仍然几乎是排序的。(有很多方法可以用这种方式拆分列表,比如每隔一秒提取一个元素,但不是列表的每个分区都有这个属性。)

这里有些不对劲–每个比较排序都需要Ω(n log n)比较才能排序√n√每个元素n个。条件x_i==x_j看起来可疑…更正版本:当存在排列pi时,列表x(1),…,x(n)几乎被排序,使得x(pi(1))@WolframH您是对的,它应该是x_i==y_j,我现在已经更正了。我可能把问题复杂化了,并且可能暗示了对问题更严格的限制。但是您不能用mergesort这样做。我们知道在更坏的情况下,一个元素只需要与2*root(n)进行比较其他元素。然后我们得到T(n)=2*T(n/2)+2*根(n)的修正mergesort递归,根据masters定理,它给出了O(n)。或者我遗漏了什么吗?它必须是这样的:让k是原始列表中的元素数,然后T(n)=根(k)*T(n/根(k))+d*根(n),这将给出O(n)但也意味着只有两个递归调用,因为第一个递归调用将是T(n/root(k))=T(root(k))(因为第一次n=k),那么第二个调用将是T(root(k)/root(k)),即T(1).但现在我觉得我是在强迫事情发生。事实就是这样。他假设分类的财产有效。他最终从作业中收回了问题