devStandard/docs/learning/c-算法/2-经典算法.md
2025-03-29 17:04:19 +08:00

147 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 前端经典算法
## 最常用的算法
* 内置的 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
}
```
## 快排
## 插入
> 将一个数据插入到已经排好序的有序数据中
> 扑克牌发牌时的理牌其实就是一种插入排序
![v2-22dc93d1df1a79f646916b63c7dba550_b|505x358](https://img.081024.xyz/v2-22dc93d1df1a79f646916b63c7dba550_b.webp)
* 从第二个位置开始, j 相当于新发的牌
![](https://img.081024.xyz/v2-042a8f91260846699db9d7c480ee66fb_b.webp)
## 递归
> 自己调用自己,就是递归
> 内存的大量占用, 通过占用空间节省运算的时间
==递归很重要的两点==
* 递归入口: 什么时候调用自己(发现相同的问题, 只是规模较小)
* 递归出口:
* 显式出口: 函数通过判断可以明确不用调用
* 函数自动运行完, 没有符合递归的条件
使用:
* 把行政区域信息, 由扁平转为树型
![|700x160](https://img.081024.xyz/1-js-1743191882193.png)
```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;
}
```
## 不常用
### 桶
### 选择