Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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
Algorithm 数组合并与排序复杂度计算_Algorithm_Sorting_Merge - Fatal编程技术网

Algorithm 数组合并与排序复杂度计算

Algorithm 数组合并与排序复杂度计算,algorithm,sorting,merge,Algorithm,Sorting,Merge,我在我的算法课本上有一个练习,我对解决方案不是很确定。我需要解释此解决方案的原因: function array_merge_sorted(array $foo, array $bar) { $baz = array_merge($foo, $bar); $baz = array_unique($baz); sort($baz); return $baz; } 合并两个数组并对它们进行排序并不是最有效的,我需要提供一个最优化的解决方案,并证明不能提供更好的解决方案 我的想法是

我在我的算法课本上有一个练习,我对解决方案不是很确定。我需要解释此解决方案的原因:

function array_merge_sorted(array $foo, array $bar)
{
  $baz = array_merge($foo, $bar);
  $baz = array_unique($baz);
  sort($baz);

  return $baz;
}
合并两个数组并对它们进行排序并不是最有效的,我需要提供一个最优化的解决方案,并证明不能提供更好的解决方案

我的想法是使用一个mergesort算法,即O(nlogn),将作为参数传递的两个数组合并并排序。但是我怎样才能证明这是有史以来最好的解决方案呢?

算法 正如您所说,两个输入都已排序,您可以使用一种简单的类似拉链的方法

每个输入数组都有一个指针,指向数组的开头。然后比较两个元素,将较小的元素添加到结果中,并使用较小的元素推进数组指针。然后重复该步骤,直到两个指针都到达末尾,并且所有元素都添加到结果中

您可以在中找到一组这样的算法,我当前介绍的方法被列为“合并两个列表”

下面是一些伪代码:

函数数组合并排序(数组第一,数组第二){
数组结果=新数组(first.length+second.length);
int firstPointer=0;
int secondPointer=0;
while(firstPointer

证明 该算法显然在
O(n)
中工作,其中
n
是结果列表的大小。或者更精确地说,它是
O(max(n,n')
,其中
n
是第一个列表的大小,而
n'
是第二个列表的大小(或者
O(n+n')
,是同一组)

这显然也是最佳的,因为在某一点上,您需要至少遍历所有元素一次,以构建结果并知道最终顺序。这会产生该问题的
Omega(n)
下限,因此该算法是最佳的


一个更正式的证明假设一个更好的任意算法
A
,它解决了问题,而不至少查看每个元素(或者更精确,小于
O(n)

我们把算法没有看到的元素称为
e
。我们现在可以构造一个输入
I
,这样
e
就有一个值,该值在它自己的数组中满足顺序,但会被算法错误地放在结果数组中

我们能够为每个算法
A
这样做,并且由于
A
总是需要在所有可能的输入上正确工作,因此我们能够找到一个反例
I
,使其失败

因此,
A
不可能存在,
Omega(n)
是该问题的下限


为什么给定的算法更差 您给定的算法首先合并两个数组,这在
O(n)
中起作用,这很好。但是在这之后它对数组进行排序

排序(更精确:基于比较的排序)的下限为
Omega(n logn)
。这意味着每种算法都不可能比这更好

因此,给定算法的总时间复杂度为
O(n logn)
(因为排序部分)。这比
O(n)
更差,其他算法的复杂度和最优解也更差


然而,为了超级正确,我们还需要讨论排序-方法是否真的会产生这种复杂性,因为它不会获得任意输入,而是总是合并-方法的结果。因此,可能特定的排序方法对这种特定的inpu特别有效ts,最终产生
O(n)

但我怀疑这是否是您任务的重点。

正如您所说,两个输入都已排序,您可以使用一种简单的类似拉链的方法

每个输入数组都有一个指针,指向数组的开头。然后比较两个元素,将较小的元素添加到结果中,并将数组的指针与较小的元素一起前进。然后重复该步骤,直到两个指针都到达末尾,并将所有元素添加到结果中

您可以在中找到一组这样的算法,我当前介绍的方法被列为“合并两个列表”

下面是一些伪代码:

函数数组合并排序(数组第一,数组第二){
数组结果=新数组(first.length+second.length);
int firstPointer=0;
int secondPointer=0;
while(firstPointer

证明 该算法显然在
O(n)
中工作,其中
n
是结果列表的大小。或者更精确地说,它是
O(max(n,n')
,其中
n
是第一个列表的大小,而
n'
是第二个列表的大小(或者
O(n+n')
,是同一组)

这显然也是op
function Array<Element> mergeSorted(Array<Element> first, Array<Element> second) {
    Array<Element> result = new Array<Element>(first.length + second.length);
    int firstPointer = 0;
    int secondPointer = 0;

    while (firstPointer < first.length && secondPointer < first.length) {
        Element elementOfFirst = first.get(firstPointer);
        Element elementOfSecond = second.get(secondPointer);

        if (elementOfFirst < elementOfSecond) {
            result.add(elementOfFirst);
            firstPointer = firstPointer + 1;
        } else {
            result.add(elementOfSecond);
            secondPointer = secondPointer + 1;
        }
    }
}