【问题标题】:How to write quick sort on Node.js如何在 Node.js 上编写快速排序
【发布时间】:2016-05-06 21:20:18
【问题描述】:

我将继续尝试在 Node.js 上编写算法,就像在 Algorithms, 4th ed 一书中一样。塞奇威克,韦恩。那里有所有用 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

【问题讨论】:

  • 您需要与书中相同的实现吗?或者你需要一个有效的 javascript 快速排序算法?
  • 那么你不能调试到底是什么不工作,看看哪个步骤失败了?

标签: javascript node.js algorithm sorting


【解决方案1】:

那个实现很丑。

抱歉,我无法帮助您回答课程问题,但这里是快速排序的函数递归版本的美妙之处。永远不要在 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]));

【讨论】:

  • 我不是很漂亮
  • 为什么不呢?是一条线。您将如何在 javascript 中编写函数式递归快速排序?
  • Can`t run it on Node.js SyntaxError: Unexpected token [
  • 使用和谐标志
【解决方案2】:

您的函数 _less 使用 indexes 作为参数:

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

但你用数组元素值来调用它:

 let v = array[lo];
 while (_less(array[++i], v)

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

【讨论】:

  • 完全不需要 _less 函数。只需比较数组的元素。感谢您的帮助。
【解决方案3】:

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


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


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>

【讨论】:

    猜你喜欢
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    相关资源
    最近更新 更多