前言
排序算法可以说是最常见的算法之一了,而我们分析一个排序算法,需要从 执行效率 内存消耗 稳定性这三个方面来入手。
-
执行效率
执行代码的时间复杂度,同时比较数据的交换或者移动的次数
-
内存消耗
即空间复杂度
-
稳定性
稳定的表现是如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。不稳定即经过排序之后,相等元素之间原有的先后顺序改变。
冒泡排序
思路
每次操作只会操作两个相邻的元素,冒泡操作就是对相邻的两个元素进行比较,对比大小关系来决定两个元素是否要互换位置。
一次冒泡至少会让一个元素移动到它应该在的位置,重复 n 次就完成了 n 个数据的排序工作。
特点
优点是简单实用易于理解,缺点就是比较次数比较多,效率比较低
实现
const bubbleSort = arr => {
// 从大到小排列
const length = arr.length;
// 首先考虑数组长度只有一个或者为 0 的情况
if (length <= 1) {
return arr;
}
for (let i = 0; i <= length - 1; i++) {
// 最外层只需要循环一个数组的长度,所以到最后一个索引就可以了
// 里面的循环比外层少一个,且比较的值是当前值的后一个,所以是
for (let j = i + 1; j <= length - 1; j++) {
if (arr[i] < arr[j]) {
const temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
插入排序
插入排序又为分为 直接插入排序 和优化后的 拆半插入排序 与 希尔排序,我们通常说的插入排序是指 直接插入排序。
思路
一般人打扑克牌,整理牌的时候,都是按牌的大小(从小到大或者从大到小)整理牌的,那每摸一张新牌,就扫描自己的牌,把新牌插入到相应的位置。
插入排序的工作原理:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
步骤:
- 从第一个元素开始,该元素可以认为已经被排序; 2 .取出下一个元素,在已经排序的元素序列中从后向前扫描;
- 如果该元素(已排序)大于新元素,将该元素移到下一位置;
- 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置;
- 将新元素插入到该位置后;
- 重复步骤 2~5。
实现
const insertionSort = (array) => {
const len = array.length;
if (len <= 1) return;
let preIndex, current;
for (let i = 1; i < len; i++) {
preIndex = i - 1; // 待比较元素的下标
current = array[i]; // 当前元素
while (preIndex >= 0 && array[preIndex] > current) {
// 前置条件之一:待比较元素比当前元素大
array[preIndex + 1] = array[preIndex]; // 将待比较的元素后移一位
preIndex--; // 游标前移一位
}
if (preIndex + 1 != i) {
// 避免同一个元素赋值给自身
array[preIndex + 1] = current; //将当前元素插入预留空位
console.log('array:', array);
}
}
return array;
};
测试~
选择排序
选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。
思路
步骤:
- 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
- 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
- 重复第二步,直到所有元素均排序完毕。
实现
const selectionSort = array => {
const len = array.length;
let minIndex, temp;
for (let i = 0; i < len - 1; i++) {
minIndex = i;
for (let j = i + 1; j < len; j++) {
if (array[j] < array[minIndex]) {
// 寻找最小的数
minIndex = j; // 将最小数的索引保存
}
}
temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
console.log('array: ', array);
}
return array;
};
总结
排序算法的复杂性对比
算法可视化工具:algorithm-visualizer 是一个交互式的在线平台,可以从代码中可视化算法,还可以看到代码执行的过程。