关于广度优先查找和深度优先查找
由于最近在做的项目中设计到了虚拟dom的设计,那自然就避免不了需要对虚拟dom中的节点进行遍历/查找了,一般来说查找节点无非就两种方法 - 广度优先查找和深度优先查找,这跟我们在数据结构中学习到的树的遍历其实是一样的。ok,废话不多说,讲一下我对这两种查找方法的理解吧。
首先广度优先查找,BFS,它的一个特点就是应用到了队列的先进先出的特性,通过这个队列来存储第一次发现的节点,以便下一次的处理。
1 /** 2 * 3 * @param {*} target: 目标节点,要在哪个节点里面进行搜索 4 * @param {*} prop: 搜索索引 5 * 索引条件在isLegal()里面进行修改 6 */ 7 function breadthSearch(target){ 8 const nodeList = [target]; 9 let index = 0; 10 while (index < nodeList.length) { 11 const node = nodeList[index++]; 12 if (node.children && node.children.length > 0) { 13 for (let k in node.children) { 14 nodeList.push(node.children[k]); 15 } 16 } 17 } 18 return function(prop) { 19 let targetNodeList = []; 20 for (let node of nodeList) { 21 if(isLegal(node, prop)) { 22 targetNodeList.push(node); 23 } 24 } 25 return targetNodeList; 26 } 27 }
其次是深度优先查找,DFS,顾名思义这是一种“一探到底”的查找算法,它会一直搜索到某一个节点的最深处,再通过回溯的方法寻找到另外一个节点的最深处,以此循环。
1 /** 2 * 3 * @param {*} target: 目标节点,要在哪个节点里面进行搜索 4 * @param {*} prop: 搜索索引 5 * 索引条件在isLegal()里面进行修改 6 */ 7 function depthSearch(target){ 8 const nodeList = []; 9 const depthEach = function(item) { 10 nodeList.push(item); 11 if(item.children){ 12 for(let k in item.children){ 13 depthEach(item.children[k]); 14 } 15 } 16 } 17 depthEach(target); 18 return function(prop) { 19 let targetNodeList = []; 20 for (let node of nodeList) { 21 if(isLegal(node, prop)) { 22 targetNodeList.push(node); 23 } 24 } 25 return targetNodeList; 26 } 27 }