广度优先搜索
以二叉树的层次遍历举例:
/*
* @lc app=leetcode.cn id=102 lang=javascript
*
* [102] 二叉树的层次遍历
*
* https://leetcode-cn.com/problems/binary-tree-level-order-traversal/description/
*
* algorithms
* Medium (53.64%)
* Total Accepted: 17.4K
* Total Submissions: 32.4K
* Testcase Example: '[3,9,20,null,null,15,7]'
*
* 给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
*
* 例如:
* 给定二叉树: [3,9,20,null,null,15,7],
*
* 3
* / \
* 9 20
* / \
* 15 7
*
*
* 返回其层次遍历结果:
*
* [
* [3],
* [9,20],
* [15,7]
* ]
*
*
*/
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if (!root) {
return [];
}
const queue = [root];
const results = [];
while (queue.length) {
let count = queue.length;
const result = [];
while (count--) {
const t1 = queue.shift();
result.push(t1.val);
t1.left && queue.push(t1.left);
t1.right && queue.push(t1.right);
}
results.push(result);
}
return results;
};
深度优先搜索
/*深度优先遍历三种方式*/
let deepTraversal1 = (node, nodeList = []) => {
if (node !== null) {
nodeList.push(node);
let children = node.children;
for (let i = 0; i < children.length; i++) {
deepTraversal1(children[i], nodeList);
}
}
return nodeList;
};
let deepTraversal2 = (node) => {
let nodes = [];
if (node !== null) {
nodes.push(node);
let children = node.children;
for (let i = 0; i < children.length; i++) {
nodes = nodes.concat(deepTraversal2(children[i]));
}
}
return nodes;
};
// 非递归
let deepTraversal3 = (node) => {
let stack = [];
let nodes = [];
if (node) {
// 推入当前处理的node
stack.push(node);
while (stack.length) {
let item = stack.pop();
let children = item.children;
nodes.push(item);
// node = [] stack = [parent]
// node = [parent] stack = [child3,child2,child1]
// node = [parent, child1] stack = [child3,child2,child1-2,child1-1]
// node = [parent, child1-1] stack = [child3,child2,child1-2]
for (let i = children.length - 1; i >= 0; i--) {
stack.push(children[i]);
}
}
}
return nodes;
};
深度优先拷贝
目前只拷贝了 Object, Array
// 如果是对象/数组,返回一个空的对象/数组,
// 都不是的话直接返回原对象
// 判断返回的对象和原有对象是否相同就可以知道是否需要继续深拷贝
// 处理其他的数据类型的话就在这里加判断
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 Map(); // 记录出现过的对象,用于处理环
let target = getEmpty(origin);
if (target !== origin) {
queue.push([origin, target]);
map.set(origin, target);
}
while (queue.length) {
let [ori, tar] = queue.shift();
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;
}
function deepCopyDFS(origin) {
let stack = [];
let map = new Map(); // 记录出现过的对象,用于处理环
let target = getEmpty(origin);
if (target !== origin) {
stack.push([origin, target]);
map.set(origin, target);
}
while (stack.length) {
let [ori, tar] = stack.pop();
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;
}