排序算法及实现
1. 分类
十种常见排序算法可以分为两大类:
- 比较类:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破 O(nlogn),因此也称为非线性时间比较类排序。
- 非比较类:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。
比较类 | 非比较类 |
---|---|
冒泡排序 | 计数排序 |
快速排序 | 桶排序 |
插入排序 | 基数排序 |
希尔排序 | |
选择排序 | |
堆排序 | |
归并排序 |
2. 复杂度
名词解释:
- 时间复杂度:对排序数据的总的操作时间。反映当 n 变化时,操作时间呈现什么规律。
- 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模 n 的函数。
- 稳定性:如果 a = b,a 原本在 b 前面,排序之后 a 仍然在 b 的前面,则为稳定;如果排序之后 a 在 b 的后面,则为不稳定。
3. 实现
冒泡排序 Bubble Sort
概述:遍历数组,一次比较两个元素,把小的放在前面、大的放在后面;重复进行直到不需要交换为止。
- a.比较第一个和第二个元素,如果第一个大就和第二个换位置
- b.重复步骤 a 的操作比较第二和第三个,第三和第四个…
- c.对每一个元素重复步骤 a 和 b,除了最后一个
JavaScript 实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function bubbleSort(arr) {
if (
Object.prototype.toString.call(arr) !== '[object Array]' ||
arr.some(item => typeof item !== 'number')
) {
throw Error('Please pass an array of numbers!');
}
if (arr.length <= 1) {
return arr;
}
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
arr[j] = arr[j] ^ arr[j + 1];
arr[j + 1] = arr[j] ^ arr[j + 1];
arr[j] = arr[j] ^ arr[j + 1];
}
}
}
return arr;
}
console.log(bubbleSort([1, 6, 2, 8, 3, 4, 5, 9, 7, 0]));
归并排序 Merge Sort
概述:归并算法采用的是分治法(Divide and Conquer)
- 把长度为 n 的输入数组分成两个长度为 n/2 的子数组
- 对这个两个子数组分别做归并排序
- 将两个排序好的子数组再排序合并成最终的数组
JavaScript 实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function mergeSort(arr) {
if (
Object.prototype.toString.call(arr) !== '[object Array]' ||
arr.some(item => typeof item !== 'number')
) {
throw Error('Please pass an array of numbers!');
}
if (arr.length <= 1) {
return arr;
}
const midPosition = Math.floor(arr.length / 2);
const leftArray = arr.slice(0, midPosition);
const rightArray = arr.slice(midPosition);
return merge(mergeSort(leftArray), mergeSort(rightArray));
}
function merge(leftArray, rightArray) {
const result = [];
while (leftArray.length > 0 && rightArray.length > 0) {
if (leftArray[0] <= rightArray[0]) {
result.push(leftArray.shift());
} else {
result.push(rightArray.shift());
}
}
return result.concat(leftArray).concat(rightArray);
}
console.log(mergeSort([1, 6, 2, 8, 3, 4, 5, 9, 7, 0]));
本文属原创,转载请联系:jeff.doyle@foxmail.com