冒泡排序
原理
相邻两个数据的按条件交换排序,然后遍历式的交换排序。何为冒泡?每次遍历为一次 冒泡,一次遍历完成,冒泡结束至少会让一个元素移动到正确的位置。列:
冒泡排序
原理
相邻两个数据的按条件交换排序,然后遍历式的交换排序。何为冒泡?
每次遍历为一次 冒泡
,一次遍历完成,冒泡结束至少会让一个元素移动到正确的位置。
列:
const arr = [3, 2, 1]; // 第1次冒泡后[2, 1,3] 3移动到正确位置 // 第2次冒泡后[1,2,3] 2移动到正确位置
它排序需要两次循环来设计:
第一层循环控制排序arr.length - 1
次
第二层循环负责每次交换遍历数据的相邻数据交换, 共arr.length - 1 - i
次,i
第一层循环 已循环次数。
代码
export const mySort = 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]) { const temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; };
实现array.sort
:
export const mySort = (arr, fn) => { for (let i = 0; i < arr.length - 1; i++) { // 控制循环次数 for (let j = 0; j < arr.length - i - 1; j++) { // 数据交换 if (fn(arr[j], arr[j + 1])) { const temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; }; mySort([1, 5, 3, 8, 2, 4], (a, b) => a > b); // [1, 2, 3, 4, 5, 8] mySort([1, 5, 3, 8, 2, 4], (a, b) => a < b); // [8, 5, 4, 3, 2, 1]
选择排序
原理
对数组遍历后选取符合条件(最大或最小)的数,与数组对应位置的数进行交换。何为选择?
每次遍历为一次 选择
,一次遍历完成结束会得出一个符合条件的元素并交换位置。
列:
const arr = [3, 2, 1]; // 第1次选择后[1, 2,3] 1与3交换位置 // 第2次选择后[1, 2,3]
它与冒泡排序不同的是它不会频繁的发生交换,第一层循环结束后,看条件是否满足需要交换。
它排序需要两次循环来设计:
第一层循环控制排序arr.length - 1
次
第二层循环负责找出交换下标index
, j = i
j前面已排好。
代码
export const mySort = (arr, fn) => { for (let i = 0; i < arr.length - 1; i++) { // 控制循环次数 let index = i; for (let j = i; j < arr.length; j++) { // 找出下标 if (fn(arr[j], arr[index])) { index = j; } } // 交换数据 if (index !== i) { const copy = arr[index]; arr[index] = arr[i]; arr[i] = copy; } } return arr; }; mySort([9, 5, 3, 4], (a, b) => a > b); // [9, 5, 4, 3]
插入排序
原理
以下内容来自参考文章:@插入排序通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
一般来说,插入排序都采用 in-place 在数组上实现:
- 从第一个元素开始,该元素可以认为已经被排序;
- 取出下一个元素,在已经排序的元素序列中从后向前扫描;
- 如果该元素(已排序)大于新元素,将该元素移到下一位置;
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
- 将新元素插入到该位置后;
- 重复步骤2~5。
动图展示
代码
const insertion = arr => { const len = arr.length; let preIndex; let current; for (let i = 1; i < len; i++) { preIndex = i - 1; current = arr[i]; while (preIndex >= 0 && current < arr[preIndex]) { arr[preIndex + 1] = arr[preIndex]; preIndex--; } arr[preIndex + 1] = current; } return arr; }; insertion([3, 5, 7, 1, 4, 56, 12, 78, 25, 0, 9, 8, 42, 37]); // [0, 1, 3, 4, 5, 7, 8, 9, 12, 25, 37, 42, 56, 78]
快速排序
原理
快速排序使用分治法策略来把一个数组分为两个数组,再重复把这两个数组变成四个,直至length <= 1
。 思路:
- 从数组中挑出一个元素,称为 "基准"。
- 重新排序数组,所有元素比基准值小的摆放在基准前面(left),所有元素比基准值大的摆在基准的后面(right),相同的数可以到任一边。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区操作。
- 递归 地把小于基准值元素的数组和大于基准值元素的数组排序,重复1~2。
代码
const quickSort = arr => { const len = arr.length; if (len <= 1) return arr; // 基准 const num = arr[0]; // 左右分区 const left = []; const right = []; for (let index = 1; index < arr.length; index++) { arr[index] <= num ? left.push(arr[index]) : right.push(arr[index]); } // 递归 return quickSort(left).concat([num], quickSort(right)); }; console.log(quickSort([3, 2, 6, 8, 99, 2, 3]));// [2, 2, 3, 3, 6, 8, 99]
以上就是详解js中常用4个基础算法的详细内容,更多关于js基础算法的资料请关注好代码网其它相关文章!