如何在Node.js上编写快速排序(Bentley-McIlroy三向分区方案)?

时间:2016-01-30 13:37:47

标签: javascript node.js algorithm sorting

我继续尝试在Node.js上编写算法,就像Algorithms,4th ed。 Sedgewick,韦恩。所有的例子都是用Java编写的。

我有这个快速排序X模块:

"use strict";

const insertion = require('./insertion-sort');

module.exports = (function () {

  let _cutoff = 10;

  function sort(array) {
    _sort(array, 0, array.length - 1);
  }

  function _sort(array, lo, hi) {
    let size = hi - lo + 1;

    if (size <= _cutoff) {
      insertion.sort(array, lo, hi);
    } else {
      let eps = Math.floor(size/8);
      let mid = Math.floor(lo + size/2);
      let m1 = _median3(array, lo, lo + eps, lo + eps + eps);
      let m2 = _median3(array, mid - eps, mid, mid + eps);
      let m3 = _median3(array, hi - eps - eps, hi - eps, hi);

      let ninther = _median3(array, m1, m2, m3);
      _exch(array, ninther, lo);
    }

    let i = lo;
    let j = hi + 1;
    let p = lo;
    let q = hi + 1;
    let v = array[lo];

    while (true) {
      while (array[++i] < v) {
        if (i === hi) {
          break;
        }
      }
      while (v < array[--j]) {
        if (j === lo) {
          break;
        }
      }

      if (i === j && array[i] === v) {
        _exch(array, ++p, i);
      }

      if (i >= j) {
        break;
      }
      _exch(array, i, j);

      if (array[i] === v) {
        _exch(array, ++p, i);
      }
      if (array[j] === v) {
        _exch(array, --q, j);
      }
    }

    i = j + 1;

    for (let k = lo; k <= p; k++) {
      _exch(array, k, j--);
    }
    for (let k = hi; k >= q; k--) {
      _exch(array, k, i++);
    }

    _sort(array, lo, j);
    _sort(array, i, hi);
  }

  function _median3(array, i, j, k) {
    return (array[i] < array[j] ?
      (array[j] < array[k] ? j : array[i] < array[k] ? k : i) :
      (array[k] < array[j] ? j : array[k] < array[i] ? k : i));
  }

  function _exch(array, i, min) {
    let temp = array[i];
    array[i] = array[min];
    array[min] = temp;
  }

  return {
    sort: sort
  };

})();

我使用mocha和chai进行测试:

function isSorted(array) {
  for(let i = 1, size = array.length; i < size; i++) {
    if (array[i] < array[i-1]) {
      return false;
    }
  }
  return true;
}

快速排序不起作用。代码循环。我需要与书中相同的实现,但是在js。

您可以在此处查看原始实施:quick sort X in java

2 个答案:

答案 0 :(得分:0)

在if else的{​​{1}}分支中,您应该执行所有快速排序代码,而不仅仅是中位数选择。 Currect代码调用惯性排序,然后执行qsort代码的一部分。

为自己发现调试的强大功能。制作简单的数据集并检查实施的每个步骤。

答案 1 :(得分:0)

您有默认的快速排名实施

// 3 way quicksort

    function sort(a, lo, hi) {
        if(hi <= lo) return a;
        var lt = lo, gt = hi;
        var v = a[lo];
        var i = lo
        while(i <= gt)
        {
            if(a[i] < v) {
                swap(a, lt, i)
                i++;
                lt++
            } else if(a[i] > v) {
                  swap(a, i, gt)
                  gt--;
            } else {
                i++;
            }

        }
        sort(a, lo, lt - 1)
        sort(a, gt + 1, hi)
    }

但是,您可以改进此算法

ValueError