[英]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.