如何在Node.js上编写快速排序

时间:2016-01-29 07:56:18

标签: javascript node.js algorithm sorting

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

我有这个快速排序模块:

"use strict";

const _ = require('lodash');

module.exports = (function () {

  function _partition(array, lo, hi) {
    let i = lo;
    let j = hi + 1;
    let v = array[lo];

    while (true) {
      while (_less(array[++i], v)) {
        if (i === hi) {
          break;
        }
      }
      while (_less(v, array[--j])) {
        if (j === lo) {
          break;
        }
      }
      if (i >= j) {
        break;
      }
      _exch(array, i, j);
    }
    _exch(array, lo, j);
    return j;
  }

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

  function _sort(array, lo, hi) {
    if (hi <= lo) {
      return null;
    }

    let j = _partition(array, lo, hi);

    _sort(array, lo, j - 1);
    _sort(array, j + 1, hi);
  }

  function _less(array, i, min) {
    return array[i] < array[min];
  }

  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 in java

3 个答案:

答案 0 :(得分:1)

这种实施很难看。

抱歉,我无法帮助您回答课程问题,但这里是quicksort功能递归版本的美妙之处。永远不要在javascript中使用上述内容。

在ES6中

功能递归快速排序。

const quicksort = ([head, ...tail]) => head === undefined ? [] : 
  [...quicksort([...tail.filter(a => a <= head)]), head, ...quicksort([...tail.filter(a => a > head)])];

<强>用法

console.log(quicksort([1,3,1,0,6,8,9,12,15,22,54, 111,12,2,3,4,5,6,7,-1]));

答案 1 :(得分:0)

您的函数_less使用索引作为参数:

  function _less(array, i, min) {
    return array[i] < array[min];

但是您使用数组元素值

来调用它
 let v = array[lo];
 while (_less(array[++i], v)

(并省略第一个参数array - 它在JS中是合法的吗?)

答案 2 :(得分:0)


<块引用>

我能想到的最简单(最易读)的快速排序功能。


快速排序(可读性是重点)


let quickSort = (items = [], left = [], right = []) => {
    if (items.length <= 1) return items
    
    let pivot = items.pop()
    let pushToSide = item => (item < pivot ? left : right).push(item)
    
    items.forEach(pushToSide)

    return [...quickSort(left), pivot, ...quickSort(right)]
}

<块引用>

注意:上面同样的逻辑的另外两种写法如下


for 循环代替 foreach


let quickSort = (arr = [], left = [], right = []) => {
    if (arr.length <= 1) return arr;
    
    let pivot = arr.pop();
    
    for (let i = 0; i < arr.length; i++) 
        (arr[i] < pivot ? left : right).push(arr[i]);
    
    return [...quickSort(left), pivot, ...quickSort(right)];
}

<块引用>

_ 在 items.forEach 中使用匿名回调函数进行快速排序,而不是通过回调传递变量_


匿名 ForEach 回调


let quickSort = (items = [], left = [], right = []) => {
    if (items.length <= 1) return items;
    
    let pivot = items.pop();

    items.forEach(item => (item < pivot? left : right).push(item)) 
    
    return [...quickSort(left), pivot, ...quickSort(right)];
}


在 js/node.js 中创建的其他类型的简短列表以及对一些有用链接的引用


let sort = {
  quick: (items = [], left = [], right = []) => {
    if (items.length <= 1) return items

    let pivot = items.pop()
    let pushToSide = item => (item < pivot ? left : right).push(item)

    items.forEach(pushToSide)

    return [...sort.quick(left), pivot,...sort.quick(right)]
  },


  bubble: (items = []) => {
    for (let passover = 0; passover < items.length; passover++)
    {
      for (let index = 0; index < items.length; index++)
      {
        if (items[index] > items[index + 1])
        {
          let temporary = items[index]
          items[index] = items[index + 1]
          items[index + 1] = temporary
        }
      }
    }

    return items;
  },

  select: (items = []) => {
    for (let passes = 0; passes < items.length; passes++)
    {
      let min = passes 

      for (let i = passes; i < items.length; i++)
      {
        if (items[i] < items[min]) {
          min = i
        }
      }

      if (min !== passes) {
        let temporary = items[passes]
        items[passes] = items[min]
        items[min] = temporary
      }
    }

    return items
  },

  insert: (items = []) => {
    for (let i = 1; i < items.length; i++)
    {
      let index = i-1
      let temporary = items[i]

      while (index >= 0 && items[index] > temporary)
      {
        items[index + 1] = items[index]

        index--
      }

      items[index + 1] = temporary
    }
    
    return items
  },

}

console.log('quick: ', sort.quick([0,43,3,2,3,4]))
console.log("select: ", sort.select([0,43,3,2,3,4]))
console.log("insert: ", sort.insert([0,43,3,2,3,4]))
console.log("bubble: ", sort.bubble([0,43,3,2,3,4]))
<ul>
<li>sort.quick O(n log n) avgerage time complexity</li>
<li>sort.bubble O(n^2) average time complexity</li>
<li>sort.insert O(n^2) average time complexity</li>
<li>sort.select O(n^2) average time complexity</li>
<li><a href="https://www.toptal.com/developers/sorting-algorithms">Watch how different sorting algorithms compare in real time</a></li>
<li>
<a href="https://bigocheatsheet.com">Time Complexity/Space Complexity cheat sheet</a></li>
</ul>