修改mergesort以计算JavaScript中的反转

时间:2014-11-25 16:07:08

标签: javascript algorithm mergesort

我的问题是,有没有更好的方法来优化下面的代码?每次合并一个数组时,inversions都会重置并递增,并且在2个排序数组(左半部分和右半部分)的最终合并中,我们得到inversions的最终值。没有全局变量,有没有更好/更清洁的做事方式?谢谢!

var inversions = 0;
  function mergeSortedArray(a, b){
    var merged = [], 
        aElm = a[0],
        bElm = b[0],
        i = 1,
        j = 1,
        inversions = 0;
    while(aElm || bElm){
     if((aElm && !bElm) || aElm < bElm){
       merged.push(aElm);
       aElm = a[i++];
     }   
     else {
       merged.push(bElm);
       bElm = b[j++];
       inversions++;
     }
    }
    return merged;
  }

  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);

      return mergeSortedArray(mergeSort(left), mergeSort(right));
  }

1 个答案:

答案 0 :(得分:0)

优化往往是丑陋的。 : - )

我看到的主要性能问题是有很多创建数据被丢弃为垃圾。要解决这个问题,你可以做的是输入数组和输出数组。您将合并函数传递给两个数组,以及两个块要合并的索引。返回反转次数。在合并排序的每个级别,输入和输出数组的角色都会交换。

代码将是挑剔,棘手,难以阅读。但应该表现得更好。

至于全局,在你的代码中处理它的“理论上正确”的方法是返回包含数组和计数的数据结构。然而,下一个最佳(并且在我看来更喜欢)的方式是围绕通过全局进行通信的函数放置一个块。在mergeSort中对其进行初始化,在mergeSortedArray中使用它并将该例程重命名为_mergeSortedArray,以表明它是私有的,不应该被调用。这将保持可读性,同时保证正确使用现在更好的本地化全局。