虽然说前端对于算法的要求不高,但是我个人认为对于简单的算法还是有必要知道的,至少在面试时就会经常会被问到,单单这一点就值得我们去学习一点了吧,还记得有一次面试时,面试官给了张纸和笔,让写个冒泡排序,当时在那提个笔愣是顿了半天。。。下面就简单的对于比较常见的排序算法进行一个实现。
算法概述
算法分类
常见的算法可以分为两大类:
算法复杂度
相关概念
稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。
冒泡排序(Bubble Sorrt)
1.1 算法描述
- 先遍历数组,比较相邻的两个元素,如果前一个比后一个大,那么久交换两个元素的位置
- 数组遍历一遍后,那么最后一个数字就是最大的那个数了
- 那么针对所有的元素重复以上的步骤,是不是就可以将数组排好序
1.2 动图演示
1.3 实现
function bubbleSort(arr) {
for (let i = 0; i<arr.length; i++){
for (let j = 0; j<arr.length; 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;
}
// 这样冒泡排序就写好了,但是我们还需要做一些优化
// 在每次排序的时候最后的一个数还需要排吗? 显然是不需要的,它就是最小的那个
// 还有第一次排序完,最后一个就是最大的了,第二次排完后面的两个也是排好的,以次类推,可以少排(i - 1)次
// 两个数交换可以采用数组的解构赋值交换 [a,b] = [b,a]
function bubbleSort(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+1]] = [arr[j+1],arr[j]]
}
}
}
return arr;
}
// 至此一个冒泡排序就写好了^_^
选择排序(Select Sort)
2.1 算法描述
- 在未排序的数组中找到最小(大)元素,放到起始(末尾)位置
- 然后从剩下的未排序的元素中继续寻找最小(大)元素,放到已排序的起始(末尾)位置
- 以此类推,知道所有元素排序完
2.2 动图演示
2.3 代码实现
function selectSort(arr) {
for (let i = 0; i < arr.length; i++){
for (let j = i+1; j < arr.length; j++){
if (arr[j] < arr[i]) {
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
}
return arr;
}
插入排序(Insert Sort)
3.1 算法描述
- 从第一个元素开始,该元素可以认为已经被排序;
- 取出下一个元素,在已经排序的元素序列中从后向前扫描;
- 如果该元素(已排序)大于新元素,将该元素移到下一位置;
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
- 将新元素插入到该位置后;
- 重复步骤2~5。
3.2 动图演示
3.3 代码实现
function insertSort(arr) {
for (let i = 1; i < arr.length; i++) {
for (let j = i; j > 0; j--) {
if (arr[j - 1] > arr[j]) {
[arr[j - 1], arr[j]] = [arr[j], arr[j - 1]];
}
}
}
return arr;
}
快速排序
4.1 算法描述
- 先找到一个基准点(一般指数组的中部),然后数组被该基准点分为两部分,依次与 该基准点数据比较,如果比它小,放左边;反之,放右边。
- 左右分别用一个空数组去存储比较后的数据。
- 最后递归执行上述操作,直到数组长度 <= 1;
4.2 动图演示
4.3 代码实现
function quikeSort(arr) {
if (arr.length <= 1) {
return arr;
}
let left = [],
right = [],
current = arr.splice(Math.floor(arr.length/2), 1);
for (let i = 0; i < arr.length; i++) {
if (arr[i] < current[0]) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quikeSort(left).concat(current, quikeSort(right));
}