如何用BFS和DFS遍历Dom树?

3,856 阅读2分钟

看看树

先来看一颗Dom树,html代码如下

<div id="container">
	<div class="node_1">
		<div class="node_1_1"></div>
		<div class="node_1_2"></div>
		<div class="node_1_3"></div>
	</div>
	<div class="node_2">
		<div class="node_2_1"></div>
		<div class="node_2_2"></div>
	</div>
	<div class="node_3"></div>	
</div>

对应的Dom图片如下(用Word画的,本灵魂画手实在尽力了。。)

从图片中我们可以直观的看出:

BFS遍历结果:#container,node_1, node_2 ,node_3, node_1_1, node_2_1, node_2_2

DFS遍历结果:#container,node_1,node_1_1,node_2,node_2_1,node_2_2,node_3

BFS(广度优先遍历)

BFS从一个节点开始,尝试访问尽可能靠近它的目标节点。本质上这种遍历在图上是逐层移动的,首先检查最靠近第一个节点的层,再逐渐向下移动到离起始节点最远的层。简单来说在树中BFS其实就是层次遍历。

步骤:

  • 创建一个队列,并将开始节点放入队列中
  • 若队列非空,则从队列中取出第一个节点,并检测它是否为目标节点
  • 若是目标节点,则结束搜寻,并返回结果 若不是,则将它所有没有被检测过的字节点都加入队列中
  • 若队列为空,表示图中并没有目标节点,则结束遍历

代码:

const parentDOM = document.getElementById('container');
function breathTravalSal(node){
	const nodes = [];
	const queue = [];
	if(node){
		queue.push(node);
		while(queue.length){
			const item = queue.shift();
			nodes.push(item);
			for(const v of item.children){
				queue.push(v);
			}
		}
	}
	return nodes;
}
console.log(breathTravalSal(parentDOM));

输出结果:

DFS(深度优先遍历)

DFS就是从图中的一个节点开始追溯,直到最后一个节点,然后回溯,继续追溯下一条路径,直到到达所有的节点,如此往复,直到没有路径为止。

步骤:

  • 访问顶点v
  • 依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问
  • 若此时途中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到所有顶点均被访问过为止

代码:

const parentDOM = document.querySelector('#container');
function  deepTravalSal(node){
	const nodes = [];
	const stack = [];
	if(node){
		stack.push(node);
		while(stack.length){
			const item = stack.pop();
			const len = item.children.length;
			nodes.push(item);
			for(let i = len - 1; i >= 0; i--){
				stack.push(item.children[i])
			}
		}
	}
	return nodes;
}
console.log(deepTravalSal(parentDOM));

输出结果:

输出正确~

小结:

把学过的算法知识用在了前端上,舒坦~