迭代地实现合并排序

时间:2015-08-16 23:55:13

标签: javascript algorithm sorting

我正在尝试实现合并排序,以便更好地了解它的工作原理。在下面的代码中,我试图对一组数字进行排序。我目前拥有的代码是错误的,并且在无限循环中运行。我现在试图非递归地解决这个问题:

function mergeSort(arr) {

  var mid = Math.floor(arr.length/2);
  var left = arr.slice(0, mid);
  var right = arr.slice(mid, arr.length);

  if (arr.length === 1) {return arr};

  var sorted = [];

  var i = 0;

  while (left.length || right.length) {
   if (left.length && right.length) {
     if (left[0] < right[0]) {
       sorted.push(left.shift())
     } else {
       sorted.push(right.shift())
     }
   } else if (left) {
     sorted.push(left.shift())
   } else {
     sorted.push(right.shift())
   }
   i++;
  }

  return sorted;
}

因此,如果我有一个数组var nums = [1, 4, 10, 2, 9, 3];,则mergeSort(nums)应该返回[1, 2, 3, 4, 9, 10]

1 个答案:

答案 0 :(得分:1)

您编写的代码将数组分成两部分并合并了一半。这不会导致排序数组,因为两个半部分没有排序。 Mergesort通过对两半进行排序,然后合并它们来工作。

有许多方法可以迭代地实现mergesort。我来提供一个。首先合并大小为1的子数组。您知道大小为1的数组已经排序,因此合并两个大小为1的连续子数组是安全的。如果对大小为1的所有连续子数组执行此操作在原始数组中,最终得到一个由大小为2的连续排序子数组组成的数组。

你知道这是怎么回事吗?现在,您可以合并每两个大小为2的连续子数组。最终得到一个大小为4的连续排序子数组的数组。继续重复此过程,直到整个数组已排序。

以下代码段实现了这种方法。

&#13;
&#13;
function mergeSort(arr) {
  var sorted = arr.slice(),
      n = sorted.length,
      buffer = new Array(n);

  for (var size = 1; size < n; size *= 2) {
    for (var leftStart = 0; leftStart < n; leftStart += 2*size) {
      var left = leftStart,
          right = Math.min(left + size, n),
          leftLimit = right,
          rightLimit = Math.min(right + size, n),
          i = left;
      while (left < leftLimit && right < rightLimit) {
        if (sorted[left] <= sorted[right]) {
          buffer[i++] = sorted[left++];
        } else {
          buffer[i++] = sorted[right++];
        }
      }
      while (left < leftLimit) {
        buffer[i++] = sorted[left++];
      }
      while (right < rightLimit) {
        buffer[i++] = sorted[right++];
      }
    }
    var temp = sorted,
        sorted = buffer,
        buffer = temp;
  }

  return sorted;
}

function print(s) {
  document.write(s + '<br />');
}

var data = [1, 4, 10, 2, 9, 3];
print('input: ' + data.join(', '));
print('output: ' + mergeSort(data).join(', '));
&#13;
&#13;
&#13;