147 lines
3.4 KiB
Markdown
147 lines
3.4 KiB
Markdown
# 前端经典算法
|
||
|
||
## 最常用的算法
|
||
|
||
* 内置的 sort (): 低效
|
||
* 快排: 高效
|
||
* 插入: n <= 10, 部分有序
|
||
|
||
## 冒泡
|
||
|
||
> 理解算法用
|
||
|
||
```js
|
||
function bubbleSort(arr) {
|
||
let n = arr.length;
|
||
for (let i = 0; i < n - 1; i++) {
|
||
for (let j = 0; j < n - 1 - i; j++) {
|
||
if (arr[j] > arr[j + 1]) {
|
||
// 交换元素
|
||
let temp = arr[j];
|
||
arr[j] = arr[j + 1];
|
||
arr[j + 1] = temp;
|
||
}
|
||
}
|
||
}
|
||
return arr;
|
||
}
|
||
|
||
// 示例用法
|
||
let array = [64, 34, 25, 12, 22, 11, 90];
|
||
console.log("排序前: " + array);
|
||
let sortedArray = bubbleSort(array);
|
||
console.log("排序后: " + sortedArray);
|
||
```
|
||
|
||
可以进行优化: 如果内层循环一次交换也没发生, 说明已经排序正确, 提前结束
|
||
|
||
```js
|
||
function bubbleSort(arr) {
|
||
let n=arr.length
|
||
for(i=0; i<n-1; i++) {
|
||
let swapen = false
|
||
for(j=0; j<n-1-i; j++){
|
||
if(arr[j]>arr[j+1]){
|
||
let temp = arr[j]
|
||
arr[j] = arr[j+1]
|
||
arr[j+1] = temp
|
||
swapen = true
|
||
}
|
||
}
|
||
if(!swapen){
|
||
break
|
||
}
|
||
}
|
||
return arr
|
||
}
|
||
```
|
||
|
||
## 快排
|
||
|
||
## 插入
|
||
|
||
> 将一个数据插入到已经排好序的有序数据中
|
||
> 扑克牌发牌时的理牌其实就是一种插入排序
|
||
|
||

|
||
|
||
* 从第二个位置开始, j 相当于新发的牌
|
||
|
||

|
||
|
||
## 递归
|
||
|
||
> 自己调用自己,就是递归
|
||
> 内存的大量占用, 通过占用空间节省运算的时间
|
||
|
||
==递归很重要的两点==
|
||
|
||
* 递归入口: 什么时候调用自己(发现相同的问题, 只是规模较小)
|
||
* 递归出口:
|
||
* 显式出口: 函数通过判断可以明确不用调用
|
||
* 函数自动运行完, 没有符合递归的条件
|
||
|
||
使用:
|
||
|
||
* 把行政区域信息, 由扁平转为树型
|
||
|
||

|
||
|
||
```js
|
||
/** *
|
||
*
|
||
* 将列表型的数据转化成树形数据 => 递归算法 => 自身调用自身 => 一定条件不能一样, 否则就会死循环
|
||
* 遍历树形 有一个重点 要先找一个头儿
|
||
* ***/
|
||
export function tranListToTreeData(list, rootValue) {
|
||
let arr = []
|
||
list.forEach(item => {
|
||
if (item.pid === rootValue) {
|
||
// 找到之后 就要去找 item 下面有没有子节点
|
||
const children = tranListToTreeData(list, item.id)
|
||
if (children.length) {
|
||
// 如果children的长度大于0 说明找到了子节点
|
||
item.children = children
|
||
}
|
||
arr.push(item) // 将内容加入到数组中
|
||
}
|
||
})
|
||
return arr
|
||
}
|
||
```
|
||
|
||
1. **递归思想**:从顶级节点(parentId=0)开始,为每个节点查找其直接子节点
|
||
2. **终止条件**:当找不到更多子节点时,递归结束
|
||
3. **时间复杂度**:O(n^2) 对于每个节点都要遍历整个数组查找子节点
|
||
4. 优化: 使用 map() 建立映射表
|
||
|
||
```js
|
||
function tranListToTreeData(data, rootValue) {
|
||
// 1. 创建id到节点的映射
|
||
const nodeMap = new Map();
|
||
data.forEach(item => {
|
||
nodeMap.set(item.id, { ...item, children: [] });
|
||
});
|
||
|
||
// 2. 构建树结构
|
||
const tree = [];
|
||
nodeMap.forEach(node => {
|
||
if (node.parentId === rootValue) {
|
||
tree.push(node);
|
||
} else {
|
||
const parent = nodeMap.get(node.parentId);
|
||
if (parent) {
|
||
parent.children.push(node);
|
||
}
|
||
}
|
||
});
|
||
|
||
return tree;
|
||
}
|
||
```
|
||
|
||
## 不常用
|
||
|
||
### 桶
|
||
|
||
### 选择 |