vlambda博客
学习文章列表

广度优先遍历、深度优先遍历

概念


广度优先遍历BFS是从根节点开始,一层一层的遍历,下一层的必须等上一层遍历完成才可以被访问。优先遍历的节点会被加入一个先进先出的队列中。

1、把根节点放到队列的末尾。

2、每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。

3、遍历所有元素结束。


深度优先遍历DFS是从根节点开始,对每一个可能的分之路径深入到不能在深入为止,而且每个节点只能访问一次。


1、把根节点压入栈中。

2、每次从栈中弹出一个元素,搜索所有在它下一级的元素,把这些元素压入栈中。并把这个元素记为它下一级元素的前驱。

3、遍历所有元素结束。


深度优先采用的是堆栈的形式,即先进后出。

广度优先采用的是队列的实行,即先进先出。



例子


1、广度优先遍历

function getEmpty(o){ if(Object.prototype.toString.call(o) == '[object Object]'){ return {}; } if(Object.prototype.toString.call(o) == '[object Array]'){ return []; } return o;}
function deepCopyBFS(origin){ let queue = []; let map = new WeakMap();
let target = getEmpty(origin); if(target!=origin){ queue.push([origin, target]); map.set(origin, target); }
while(queue.length){ let [ori, tar] = queue.shift(); console.log(ori); for(let key in ori){ if(map.get(ori[key])){ tar[key] = map.get(ori[key]); continue; }
tar[key] = getEmpty(ori[key]); if(tar[key]!==ori[key]){ queue.push([ori[key],tar[key]]); map.set(ori[key], tar[key]); } } } return target;}
let sourceObj = { a: { a1: 'a1', a2: 'a2', a3: { aa1: 'aa1' } }, b: { b1: 'b1' } };deepCopyBFS(sourceObj);

广度优先遍历、深度优先遍历



2、深度优先遍历

function getEmpty(o){ if(Object.prototype.toString.call(o) == '[object Object]'){ return {}; } if(Object.prototype.toString.call(o) == '[object Array]'){ return []; } return o;}
function deepCopyDFS(origin){ let stack = []; let map = new WeakMap();
let target = getEmpty(origin); if(target!==origin){ stack.push([origin, target]); map.set(origin, target); }
while(stack.length){ let [ori, tar] = stack.pop(); console.log(ori); for(let key in ori){ if(map.get(ori[key])){ tar[key] = map.get(ori[key]); continue; }
tar[key] = getEmpty(ori[key]); if(tar[key]!==ori[key]){ stack.push([ori[key], tar[key]]); map.set(ori[key], tar[key]); } } } return target;}