簡體   English   中英

如何在Node.js上編寫快速排序(Bentley-McIlroy 3路分區方案)?

[英]How to write quick sort (Bentley-McIlroy 3-way partitioning scheme) on Node.js?

我繼續嘗試在Node.js上編寫算法,如《算法》(第四版)一書中所述。 韋奇塞奇威克。 有所有用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上。

您可以在此處看到原始的實現: Java中的X快速排序

在if (size <= _cutoff)else分支中,您應該執行所有快速排序代碼,而不僅是中位數選擇。 當前代碼調用慣性排序,然后執行qsort代碼的一部分。

親自發現調試的力量。 制作簡單的數據集並檢查實施的每個步驟。

那里有默認的quicksort實現

   function partioning(arr, left , right) // default qsort implementation
{
    var pivot = arr[Math.floor((left + right)/ 2)],
        i = left;
        j = right;
    var temp;
    while(i <= j)
    {
        while(arr[i] < pivot)
            i++;
        while(arr[j] > pivot)
            j--;
        if(i <= j)
        {
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }
    return i;
}
function quicksort(arr, left, right)
{
    var i = partioning(arr, left, right)

    if(left < i - 1)
        quicksort(arr, left, i - 1);
    if(right > i)
        quicksort(arr, i, right);
    return arr;
}

但是,您可以改進此算法

// 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)
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM