JavaScript 排序算法(JavaScript sorting algorithms)

来源/参考

图解

ECMAScript 1

图解

ECMAScript 2

6. ECMAScript 排序

ECMAScript没有概念用哪个排序算法,所以浏览器厂商可以活动去贯彻算法。例如,Mozilla
Firefox使用归并排序作为Array.prototype.sort的贯彻,而Chrome使用了1个便捷排序(上面大家会学习的)的变体。

this.esSort = function () {
  console.time('esSort');
  var tempArray = [];
  tempArray = array.sort(function (a, b) {
    return a - b;
  });
  console.timeEnd('esSort');
  return tempArray;
}

代码

this.bubbleSort = function () {
  console.time('Bubble Sort');
  var length = array.length;
  for (var i = 0; i < length; i++) {
    for (var j = 0; j < length - 1 - i; j++) {
      if (array[j] > array[j+1]) {
        swap(j, j + 1);
      }
    }
  }
  console.timeEnd('Bubble Sort');
}

4. 归并排序

归并排序是一种分治算法。其构思是将原始数组切分成较小的数组,直到每一个小数组唯有三个地点,接着将小数组归并成较大的数组,直到最后唯有七个排序完结的造化组。

复杂度:O(n log^n)。

JavaScrip 排序算法(JavaScript Sorting Algorithms)

图解

ECMAScript 3

代码

this.quickSort = function () {
  console.time('quickSort');
  quick(array, 0, array.length - 1);
  console.timeEnd('quickSort');
}

var quick = function (array, left, right) {
  var index;
  if (array.length > 1) {
    index = partition(array, left, right);

    if (left < index - 1) {
      quick(array, left, index - 1);
    }

    if (index < right) {
      quick(array, index, right);
    }
  }
};

// 划分过程
var partition = function (array, left, right) {
  var pivot = array[Math.floor((right + left) / 2)],
      i = left,
      j = right;

  while (i < j) {
    while (array[i] < pivot) {
      i++;
    }

    while (array[j] > pivot) {
      j--;
    }

    if (i <= j) {
      swapQuickSort(array, i, j);
      i++;
      j--;
    }
  }
  return i;
}

var swapQuickSort = function (array, index1, index2) {
  var aux = array[index1];
  array[index1] = array[index2];
  array[index2] = aux;
}

转载请申明出处: http://blog.givebest.cn/javascript/2017/08/02/javascript-sorting-algorithms.html

属性测试

代码

this.selectionSort = function () {
  console.time('selectionSort');
  var length = array.length,
      indexMin;

  for (var i = 0; i < length - 1; i++) {
    indexMin = i;
    for (var j = i; j < length; j++) {
      if (array[indexMin] > array[j]) {
        indexMin = j;
      }
    }

    if (i !== indexMin) {
      swap(i, indexMin);
    }
  }
  console.timeEnd('selectionSort');
}

代码

this.mergeSort = function () {
  console.time('mergeSort');
  array = mergeSortRec(array);
  console.timeEnd('mergeSort');
}
var mergeSortRec  = function (array) {
  var length = array.length;
  if (length === 1) {
    return array;
  }

  var mid = Math.floor(length / 2),
      left = array.slice(0, mid),
      right = array.slice(mid, length);

  return merge(mergeSortRec(left), mergeSortRec(right));
}
var merge = function (left, right) {
  var result = [],
      il = 0,
      ir = 0;

  while (il < left.length && ir < right.length) {
    if (left[il] < right[ir]) {
      result.push(left[il++]);
    } else {
      result.push(right[ir++]);
    }
  }

  while (il < left.length) {
    result.push(left[il++]);
  }

  while (ir < right.length) {
    result.push(right[ir++]);
  }

  return result;
}

1. 冒泡排序

冒泡排序比较任何七个相邻的项,假诺第三个比第③个大,则沟通它们。

复杂度 O(n^2)。

2. 摘取排序

采纳排序算法是一种原址比较排序算法。选拔排序大约的思路是找到数据结构中的最小值并将其放置在率先位,接着找到第2小的值并将其位于第④位,以此类推。

复杂度:O(n^2)。

图解

ECMAScript 4

代码

/**
* 创建随机数组
* @param  {[type]} size [description]
* @return {[type]}      [description]
*/
function createNonSortedArray (size) {
  var array = new ArrayList();
  for (var i = size; i > 0; i--) {
    var tempNum = Math.random() * i >>> 0;
    array.insert(tempNum);
  }
  return array;
}

// 冒泡排序
(function () {
  var array = createNonSortedArray(500);
  array.bubbleSort(); // Bubble Sort: 2.625ms
  console.log(array.val());
}());


// 选择排序
(function () {
  var array = createNonSortedArray(500);
  array.selectionSort(); // selectionSort: 1.986083984375ms
  console.log(array.val());
}());

// 插入排序
(function () {
  var array = createNonSortedArray(500);
  array.insertionSort(); // insertionSort: 1.825927734375ms
  console.log(array.val());
}());

// 归并排序
(function () {
  var array = createNonSortedArray(500);
  array.mergeSort(); // mergeSort: 0.76416015625ms
  console.log(array.val());
}());


// 快速排序
(function () {
  var array = createNonSortedArray(500);
  array.quickSort(); // quickSort: 0.39111328125ms
  console.log(array.val());
}());


// ES排序
(function () {
  var array = createNonSortedArray(500);
  array.esSort(); // esSort: 0.34130859375ms
  console.log(array.val());
}());

有鉴于此,一般景况我们只必要接纳JavaScript 提供的
Array.prototype.sort()
方法即可,浏览器(或宿主环境)会在底层拔取最优算法帮大家贯彻排序。

环境

  • OS:WIN10 64位

  • 浏览器:Google Chrome 60.0.3112.78

ECMAScript,5. 便捷排序

归并排序一样,火速排序也选用分治的不二法门,将原始数组分为较小的数组(但它没有像归并排序那样将它们分割开)。

它的性质一般比其余的复杂度为O(n log^n)的排序算法要好。

复杂度:O(n log^n)。

图解

ECMAScript 5
ECMAScript 6
ECMAScript 7
ECMAScript 8
ECMAScript 9

基本功构造函数

以下三种排序算法做为方法放在构造函数里。

function ArrayList () {
  var array = [];

  // 交换位置
  var swap = function (index1, index2) {
    var aux = array[index1];
    array[index1] = array[index2];
    array[index2] = aux;
  }

  this.insert = function (item) {
    array.push(item);
  };

  this.toString = function () {
    return array.join();
  };

  this.val = function () {
    return array;
  }

  // 冒泡排序
  this.bubbleSort = function () {
    //etc
  }
}

代码

this.insertionSort = function () {
  console.time('insertionSort');
  var length = array.length,
      j, temp;

  for (var i = 1; i < length; i++) {
    j = i;
    temp = array[i];
    while (j > 0 && array[j-1] > temp) {
      array[j] = array[j-1];
      j--;
    }
    array[j] = temp;
  }
  console.timeEnd('insertionSort');
}

3. 插入排序

插入排序每趟排贰个数组项,以此方法构建最终的排序数组。假定第3项已经排序了,接着,它和第一项进行相比较,第三项是应该待在原位如故插到第①项此前呢?那样,头两项就已正确排序,接着和第二项比较(它是该插入到第叁 、第叁依然第二的职务吗?),以此类推。

排序小型数组时,此算法比采用排序和冒泡排序品质要好。