开题两点
1.数据结构和算法是前端代码编写很重要也很容易被忽视的地方,所以很想分享一下数据结构和算法相关的东西
2.深度优先搜索和广度优先搜索是两种应用在图上的基础搜索。项目中用到图这种数据结构比较少,用到最多的数据结构是数组和对象,有一种没有根节点的类多叉树的数据结构,在项目中会经常遇到,这里就称为数组对象,我们一般都是通过递归来查找一些相关数据,很少使用其他方式。所以下面我们就来聊一下经典算法之深度优先搜索和广度优先搜索在数组对象中的应用。
深度优先搜索(Depth-First-Search)
简称:DFS
属于一种盲目搜索。深度优先搜索包括从一条路径的起始顶点开始追溯,直到到达最后一个顶点,然后回溯,继续追溯下一条路径,直到到达最后的顶点。如此往复,直到没有路径为止。
特点:
- js 中最常用递归来实现深度优先搜索,由于易于编写,所以应用特别广泛。
- 深度搜索的过程可以理解为抽象栈,是后进先出的一个过程。
- 深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。
存在的问题:
递归导致栈太深,容易爆栈
示例:递归调用:
const dfsByRecursion = function (array, target, params = {}) {
if (!array || !array.length) return
let {id = 'id', label = 'label', children = 'children'} = params
let result
for (let item of array) {
if (item[id] === target) {
return item[label]
} else if (item[children]) {
result = dfsByRecursion(item[children], target, {id, label, children})
if (result) {
return result
}
}
}
}
示例:非递归调用:
const dfsByWhile = function (array, target, params = {}) {
if (!array || !array.length) return
let {id = 'id', label = 'label', children = 'children'} = params
let stack = []
for (let item of array) {
stack.push(item)
}
let result
while (stack.length) {
result = stack.shift()
if (result[id] === target) {
return result
} else if (result[children] && result[children].length) {
// 加入栈顶
stack = [...result[children], ...stack]
}
}
}
广度优先搜索 (Breadth-First-Search)
简称:BFS
BFS也是一种盲目搜索,广度优先搜索从第一个顶点开始,尝试访问尽可能靠近它的顶点。本质上,这种搜索再图上是逐层移动的,首先检查最靠近第一个顶点的层,再逐渐的向下移动到离起始顶点最远的层。过程如下图
特点:
-
抽象队列,入队出队
-
主要用于求最短路径等问题
示例代码
const bfsByWhile = function (array, target, params = {}) {
if (!array || !array.length) return
let {id = 'id', label = 'label', children = 'children'} = params
let list = []
for (let item of array) {
list.push(item)
}
let result
while (list.length) {
result = list.shift()
if (result[id] === target) {
return result
} else if (result[children] && result[children].length) {
// 加入队尾
list = [...list, ...result[children]]
}
}
}
应用举例和思考:
1.vue中vnode的patch过程使用了哪种算法 ?
2.产品内哪些递归可转化为广度优先 ?
3.其他什么例子
总结
本次分享的代码为示例代码,在项目中使用时,可根据实际情况进项优化处理。以后再遇到搜索相关的时候,能打开一个思路,不要只有递归。