广度优先遍历、深度优先遍历
概念
广度优先遍历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;}
