Javascript 它是就地排序?;

Javascript 它是就地排序?;,javascript,algorithm,sorting,in-place,Javascript,Algorithm,Sorting,In Place,我读过尼古拉斯·C·扎卡斯的博客(原始链接:)。有一个问题总是让我困惑 博客用JavaScript解释了合并排序的概念,作者给出了两种合并排序的解决方案(第一种是非就地,另一种是就地) 这是我的问题:我认为解决方案1和解决方案2之间的空间复杂度没有区别。那么,我们是否应该理解,所谓的“就地排序”只与本例中的输入和输出是否为同一数组有关,而与额外的空间无关 代码如下: 解决方案1(未就地排序): 是的,这两种算法都在一个新的、不同的数组中对数据进行排序。这意味着需要额外的空间 唯一的区别是所谓的“

我读过尼古拉斯·C·扎卡斯的博客(原始链接:)。有一个问题总是让我困惑

博客用JavaScript解释了合并排序的概念,作者给出了两种合并排序的解决方案(第一种是非就地,另一种是就地)

这是我的问题:我认为解决方案1和解决方案2之间的空间复杂度没有区别。那么,我们是否应该理解,所谓的“就地排序”只与本例中的输入和输出是否为同一数组有关,而与额外的空间无关

代码如下:

解决方案1(未就地排序):


是的,这两种算法都在一个新的、不同的数组中对数据进行排序。这意味着需要额外的空间

唯一的区别是所谓的“就地排序”然后清空原始数组并用排序后的数据填充它。这是否到位取决于定义

就地算法是使用 具有少量额外存储空间的数据结构

原地踏步可能有稍微不同的含义。以最严格的形式, 不过,该算法只能有恒定的额外空间 有时
o(n)
中的任何内容都是允许的

因此通常不考虑它,因为额外的空间复杂度大于
o(n)


如果需要具有
O(n log(n))
时间复杂度和
O(1)
额外空间复杂度的就地排序算法,可以使用。缺点是,与mergesort不同,heapsort不是。

谢谢您的回复。因此,本博客中的解决方案2通常不是就地排序,因为额外的空间复杂性超过o(n)?而作者错了?@Change.Lee我不会说他错了,只是他使用了不同的“就地”定义。就像你上面发布的维基百科所说:“就地算法是一种使用具有少量额外存储空间的数据结构转换输入的算法。“我可以认为,即使有时算法需要更多的空间,比如Quask排序,只要算法在输入上操作或重写并返回它,我们仍然认为这个算法已经到位了。谢谢您的病人:”@嫦娥。李,是的,Quask排序改变了原来的数组,因此它将被认为是“就位”。根据那个博客的定义。它只需要
O(logn)
额外的空间,因此根据维基百科的定义,它也可以被认为是“就地”的(但不是以最严格的形式,这要求它是常量)。我明白了!谢谢你^ ^解决方案2最终将排序后的数据返回到条目中。就空间而言,情况更糟,因为在某个时刻,它有左、右、参数和项目。可以使用entry函数调用mergesort(),然后将数据移回项中,而不是递归地复制、返回。还有其他方法可以将数据返回到项目中,但我不确定这里的目标。@rcgldr是的,解决方案2需要更多的空间。作者说他的目的只是解释这个概念,我对空间复杂性和原地之间的关系感到困惑。
function mergeSort(items) {
  // Terminal case: 0 or 1 item arrays don't need sorting
  if (items.length < 2) {
    return items;
  }
  var middle = Math.floor(items.length / 2),
      left = items.slice(0, middle),
      right = items.slice(middle);
  return merge(mergeSort(left), mergeSort(right));
}
function mergeSort(items) {
  if (items.length < 2) {
    return items;
  }
  var middle = Math.floor(items.length / 2),
      left = items.slice(0, middle),
      right = items.slice(middle),
      params = merge(mergeSort(left), mergeSort(right));
  // Add the arguments to replace everything between 0 and last item in the array
  params.unshift(0, items.length);
  items.splice.apply(items, params);
  return items;
}
function merge(left, right){
  var result = [],
      il = 0,
      ir = 0;
  while (il < left.length && ir < right.length) {
    if (left[il] < right[ir]) {
      result.push(left[il++]);
    } else {
      result.push(right[ir++]);
    }
  }
  return result.concat(left.slice(il)).concat(right.slice(ir));
}