Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 关于数组中的就地合并_Arrays_Algorithm_Sorting_Mergesort_Space Complexity - Fatal编程技术网

Arrays 关于数组中的就地合并

Arrays 关于数组中的就地合并,arrays,algorithm,sorting,mergesort,space-complexity,Arrays,Algorithm,Sorting,Mergesort,Space Complexity,我遇到了以下问题 给定一个由n个元素组成的数组和一个整数k,其中k

我遇到了以下问题

给定一个由n个元素组成的数组和一个整数k,其中k 在我看来,它不可能在O(n)时间和O(1)空间内完成。问题似乎真的是在问如何执行mergesort的合并步骤,但要到位。如果可能的话,mergesort不是这样实现的吗?但我无法说服自己,需要一些意见

似乎表明,在O(lg^2n)空间中,这是可能的。我看不到如何证明在恒定空间中合并是不可能的,但我也看不到如何做到这一点

编辑: 根据参考文献,Knuth Vol 3-练习5.5.3说,“L.Trabb Pardo的一个相当复杂的算法为这个问题提供了最好的答案:可以在O(n)时间内进行稳定的合并,在O(n lgn)时间内进行稳定的排序,对于固定数量的索引变量,只使用辅助内存的O(lgn)位

更多我没有读过的。谢谢你提出了一个有趣的问题

进一步编辑: 这篇文章声称Huang和Langston的文章有一个算法,可以在时间O(m+n)内合并大小为m和n的两个列表,所以你的问题的答案似乎是肯定的。不幸的是,我没有这篇文章,所以我必须相信二手信息。我不知道如何将这与Knuth关于Trabb Pardo算法是最优的声明相协调。如果我的生活依赖于此,我会选择Knuth

我现在明白了,这已经被问了很多次了,我不忍心把它标记为复制品


Huang B.-C.和Langston M.A.,《实际就地合并》,通信ACM 31(1988)348-352

不,这是不可能的,尽管如果是这样,我的工作会容易得多:)

你有一个无法避免的O(logn)因素。你可以选择将其作为时间或空间,但避免它的唯一方法是不排序。有了O(logn)空间,你可以建立一个连续列表,跟踪不太合适的元素的存放位置。通过递归,可以使其适合O(1)堆,但这只能通过使用O(logn)堆栈帧来代替

以下是合并排序赔率和偶数从1到9的进度。请注意,您如何要求日志空间记帐来跟踪由常量空间和线性交换的双重约束引起的顺序反转

. - 135792468 . - 135792468 : .- 125793468 : .- 123795468 #.:- 123495768 :.- 123459768 .:- 123456798 .- 123456789 123456789 . - 135792468 . - 135792468 : .- 125793468 : .- 123795468 #.:- 123495768 :.- 123459768 .:- 123456798 .- 123456789 123456789 有一些微妙的边界条件,比二进制搜索更难获得正确的结果,甚至是以这种(可能的)形式,因此是一个糟糕的家庭作业问题;但这是一个非常好的心理练习

更新
显然我错了,有一个算法可以提供O(n)时间和O(1)空间。我下载了论文来启发自己,并以不正确的理由收回了这个答案。

有几种算法可以做到这一点,其中没有一种算法是很容易直观的。关键思想是使用数组的一部分合并为缓冲区,然后使用此缓冲区作为辅助空间进行标准合并。如果可以,然后重新定位元素,这样缓冲元素就在正确的位置,你是金色的

如果你有兴趣的话,我已经在我的个人网站上写了这些算法中的一个。它基于黄和兰斯顿的论文“实用就地合并”。你可能会想看看那篇论文以获得一些见解


我也听说有很好的自适应算法,它使用一些你选择的固定大小的缓冲区(如果你想的话可以是O(1)),然后根据缓冲区的大小进行优雅的缩放。这些我都不知道,但我确信快速搜索“自适应合并”“可能会出现问题。

问题是否特别说明合并排序?我知道可以就地合并排序,但在O(n)时间内不行(至少我从未听说过)。不,不行。我将此类比为合并步骤。它看起来确实很相似。如果你发布了问题的确切措辞,那么它似乎与mergesort没有任何关系。对于预排序数组(即插入排序),有O(1)空间和O(n)到位的排序算法。Mergesort不是其中之一,而且众所周知,它不是其中之一,所以……那么,在O(n)时间内,您将如何解决这个问题?有什么想法?也许你没有得到这个问题,这里是一个例子。。。{1,3,5,8}和{2,4,6,9}。。你指的是一个完全预先分类的数组,我的问题不是这样的。无论如何,对已排序的数组进行排序是没有意义的。对于链表,可能存在重复排序。O(logn)来自其他地方。我可以看到如何使用lgn额外的空间。“我看不出如何证明你不能做得更好,也就是说,O(lgn)额外的空间是保持事物线性的必要条件。”约书亚。说链表是可能的并不公平,因为链表中有O(n)条额外的信息使它更容易——元素之间的指针。如果您能够提供O(n)个额外空间,那么使用阵列也可以。分配一个新的结果数组,只需遍历两个原始数组,按顺序复制项目。@deinst我觉得这并不容易,但我最终满意地证明了lg n是下限。那是几年前的事了,不幸的是我已经没有了。然而,这是合理的直接证明,无论下限是什么,它都高于O(1),这对于我们这里的目的来说已经足够好了。你是对的。自从我上了大学,我就能够读这篇论文了。这似乎是可能的,尽管技术相当复杂。谢谢你的指点,你可以