冒泡排序(O(n2))
冒泡排序比较任何两个相邻的项,如果第一个比第二个大,则交换它们。元素项向上移动至 正确的顺序,就好像气泡升至表面一样,冒泡排序因此得名。
function bubbleSort(list) {
let length = list.length;
for (let i = 0; i < length; i++) {
// 从内循环减去外循环中已跑过的轮数,就可以避免内循环中所有不必要的比较
for (let j = 0; j < length - 1 + i; j++) {
if (list[j] < list[j + 1]) {
// es6交换元素
[list[j + 1], list[j]] = [list[j], list[j + 1]];
}
}
}
return list;
}
console.log(bubbleSort([5,4,3,2,1]))
选择排序(O(n2))
选择排序大致的思路是找到数据结构中的最小值并 将其放置在第一位,接着找到第二小的值并将其放在第二位,以此类推。
function selectionSort(list) {
let length = list.length,
indexMin;
for (var i = 0; i < length - 1; i++) {
// 假设当前的i为数组的最小值
indexMin = i;
for (var j = i + 1; j < length; j++) {
// 如果j的值比indexMin的值小,则把j赋值给indexMin
if (list[indexMin] > list[j]) {
indexMin = j;
}
}
// 不相等则交换元素
if (i !== indexMin) {
// es6交换元素
[list[i], list[indexMin]] = [list[indexMin], list[i]];
}
}
return list;
}
插入排序(O(n2))
插入排序每次排一个数组项,以此方式构建最后的排序数组。假定第一项已经排序了,接着, 用第二项和第一项想比较,是插入到第一项之前,还是之后,然后用第三项,去和之前的第一、第二项比较,找出插入的位置,以此类推
function insertionSort(array) {
var length = array.length,
j,
temp;
// 注意i不是从0开始的,我们认为第一项已经排序
for (let i = 1; i < length; i++) {
// 初始位置为i
j = i;
// 采用临时变量存起来
temp = array[i];
// 用于找到temp需要插入的位置j
while (j > 0 && array[j - 1] > temp) {
array[j] = array[j - 1];
j--;
}
// 插入
array[j] = temp;
}
return array;
}
归并排序(O(nlogn))
归并排序是一种分治算法(采用递归实现)。其思想是将原始数组切分成较小的数组,直到每个小数组只有一 个位置,接着将小数组归并成较大的数组,直到最后只有一个排序完毕的大数组。Firefox的Array.prototype.sort
的实现就是归并排序
function merge(left, right) {
let 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;
}
function mergeSortRec(array) {
let length = array.length;
if (length === 1) {
return array;
}
let mid = Math.floor(length / 2);
let left = array.slice(0, mid);
let right = array.slice(mid);
return merge(mergeSortRec(left), mergeSortRec(right));
}
function mergeSort(array) {
return mergeSortRec(array);
}
快速排序(O(nlogn))
最常用的排序算法,也是分治算法。Chrome的Array.prototype.sort
的实现就是快速排序
-
首先,从数组中选择中间一项作为对比项pivot。
-
创建两个指针,左边一个指向数组第一个项,右边一个指向数组最后一个项。移动左指 针直到我们找到一个比pivot的元素,接着,移动右指针直到找到一个比pivot小的元素,然后交 换它们,重复这个过程,直到左指针超过了右指针。这个过程将使得比pivot小的值都排在pivot之前,而比pivot大的值都排在pivot之后。最后返回左指针位置,继续划分
-
接着,对划分后的小数组(左边比pivot小的值组成的子数组,以及较pivot大的值组成的子数组)重复之前的两个步骤,直至数组已完全排序。
function partition(array, left, right) {
let pivot = array[Math.floor((left + right) / 2)],
i = left,
j = right;
while (i <= j) {
while (array[i] < pivot) {
i++;
}
while (array[j] > pivot) {
j--;
}
if (i <= j) {
[array[i], array[j]] = [array[j], array[i]];
i++;
j--;
}
}
return i;
}
function quick(array, left, right) {
let 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);
}
}
}
function quickSort(array) {
quick(array, 0, array.length - 1);
console.log(array);
}