我们有两个数组(未分类),容量 n 和 n + m 。第一个数组有 n 元素。第二个数组具有 m 元素(以及为更多元素保留的 n 位置)。
目标是合并两个数组并以排序的方式将结果存储在第二个数组中,而不使用额外的空间。
目前,我使用快速排序对两个数组进行排序,然后使用merge-sort合并它们。有没有更有效的方法来实现这个???
答案 0 :(得分:2)
您可以探索合并排序。
https://www.google.com/search?q=mergesort&ie=UTF-8&oe=UTF-8&hl=en&client=safari#itp=open0
或者根据大小,您可以对每个数组执行快速排序,然后使用合并排序技术(或合并,然后快速排序)合并它们。
我会选择mergesort,它基本上是通过单独排序每个数组,然后按顺序将它们组合在一起
你正在寻找关于mergesort的O(nlogn)和关于quicksort的O(nlogn),但是对于quicksort可能是O(n ^ 2)最坏的情况。
答案 1 :(得分:2)
显然,最好的办法是将N的内容复制到N + M阵列的自由空间中,并快速分配N + M阵列。
通过执行2个快速排序然后进行合并排序,您只会降低整个操作的效率。
这是一个心理练习,如果你必须对长度为M的数组进行排序,你会将它分成2个数组,M1和M2,对每个数组进行排序,然后将它们合并排序在一起吗?不会。如果您这样做,您只会限制每次快速排序电话的可用信息,从而减慢过程。
那么为什么要将两个起始阵列分开?
答案 2 :(得分:0)
如果您要存储在第二个阵列中,而不是使用额外的空间,但可以通过像这样帮助GC来最小化:
Arrays.sort(...)
- O(n log(n)) 查看此方法的javadoc:
/**
* Sorts the specified array into ascending numerical order.
*
* <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
* by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
* offers O(n log(n)) performance on many data sets that cause other
* quicksorts to degrade to quadratic performance, and is typically
* faster than traditional (one-pivot) Quicksort implementations.
*
* @param a the array to be sorted
*/
public static void sort(int[] a) {
答案 3 :(得分:0)
如果我还想保证O(n * log(n))行为,我会使用Heapsort的修改版本,它将使用这两个数组作为堆的基础,并将存储排序数据在数组的附加部分。
这也可能比两个Quicksorts更快,因为它不需要额外的合并操作。当小数组被排序时,Quicksort也非常慢(问题的大小没有提到问题的设置)。
答案 4 :(得分:0)
让我们将较小的数组称为N数组,将另一个数组称为M数组。我假设M阵列的元素最初位于0到m-1的位置。使用您喜欢的技术对两个阵列进行排序,这可能取决于其他标准,例如稳定性或限制最坏情况的行为。
if min(N) > max(M)
copy N's elements over starting at location m [O(n) time]
else
move M's elements to the end of the M array (last down to first) [O(m) time]
if min(M) > max(N)
copy N's elements over starting at location 0 [O(n) time for the copy]
else
perform classic merge: min of remaining m's and n's gets migrated
to next available space in M [O(min(m,n) time]
总的来说,这是由初始排序时间决定的,合并阶段都是线性的。将m移动到M阵列的末尾可确保没有空间冲突,因此您不需要根据规范进行额外的侧面存储。