这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战前端
分层
数据的抽象模型例:node
{
value: "zhe jiang",
label: "zhe jiang",
children: [
value: "hangzhou",
label: "hangzhou",
children: [...]
]
}
复制代码
以下分别是两种方式 遍历的顺序。json
const tree = {
val: "a",
children: [
{
val: "b",
children: [
{ val: "d", children: [] },
{ val: "e", children: [] }
]
},
{
val: "c",
children: [
{ val: "f", children: [] },
{ val: "g", children: [] }
]
}
]
}
const dfs = root => {
console.log(root.val); // a,b,d,e,c,f,g
root.children.forEach(dfs)
}
复制代码
const tree = {
val: "a",
children: [
{
val: "b",
children: [
{ val: "d", children: [] },
{ val: "e", children: [] }
]
},
{
val: "c",
children: [
{ val: "f", children: [] },
{ val: "g", children: [] }
]
}
]
}
经过队列的方式,将先遍历的放在队首,后面层级的放在队尾
const bfs = root => {
const q = [root]
while(q.length > 0) {
const n = q.shift()
console.log(n.val)
n.children.forEach(child => {
q.push(child)
})
}
}
复制代码
左
子树进行先序遍历右
子树进行先序遍历const bt = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null
},
right: {
val: 5,
left: null,
right: null
}
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null
},
right: {
val: 7,
left: null,
right: null
}
}
}
// 递归版:
const preorder = root => {
if (!root) return
console.log(root.val) // 1245 367
preorder(root.left)
preorder(root.right)
}
// 非递归版:
const preorder = root => {
if (!root) return
const stack = [root]
while(stack.length) {
const n = stack.pop()
console.log(n.val)
if (n.right) stack.push(n.right)
if (n.left) stack.push(n.left)
}
}
复制代码
const bt = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null
},
right: {
val: 5,
left: null,
right: null
}
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null
},
right: {
val: 7,
left: null,
right: null
}
}
}
// 递归版:
const inorder = root => {
if (!root) return
inorder(root.left)
console.log(root.val)
inorder(root.right)
}
复制代码
const bt = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null
},
right: {
val: 5,
left: null,
right: null
}
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null
},
right: {
val: 7,
left: null,
right: null
}
}
}
const postorder = root => {
if (!root) return
postorder(root.left)
postorder(root.right)
console.log(root.val)
}
复制代码
LeetCode-104: 二叉树最大深度markdown
**示例:**\
给定二叉树 `[3,9,20,null,null,15,7]`,
3
/ \
9 20
/ \
15 7
/** * Definition for a binary tree node. * function TreeNode(val, left, right) { * this.val = (val===undefined ? 0 : val) * this.left = (left===undefined ? null : left) * this.right = (right===undefined ? null : right) * } */
/** * @param {TreeNode} root * @return {number} */
var maxDepth = function(root) {
let res = 0;
const dfs = (n, l) => {
if (!n) return;
res = Math.max(res, l)
dfs(n.left, l + 1);
dfs(n.right, l + 1);
}
dfs(root, 1);
return res
};
复制代码
输入:root = [3,9,20,null,null,15,7]
输出:2
示例 2:
输入:root = [2,null,3,null,4,null,5,null,6]
输出:5
来源:力扣(LeetCode)
/** * Definition for a binary tree node. * function TreeNode(val, left, right) { * this.val = (val===undefined ? 0 : val) * this.left = (left===undefined ? null : left) * this.right = (right===undefined ? null : right) * } */
/** * @param {TreeNode} root * @return {number} */
var minDepth = function(root) {
if (!root) return 0;
let stack = [ [root, 1] ]
while(stack.length) {
const [n, l] = stack.shift();
console.log(n.val, l)
if (!n.left && !n.right) return l
if (n.left) stack.push([n.left, l + 1])
if (n.right) stack.push([n.right, l + 1])
}
};
复制代码
示例:
二叉树:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层序遍历结果:
[
[3],
[9,20],
[15,7]
]
来源:力扣(LeetCode)
/** * Definition for a binary tree node. * function TreeNode(val, left, right) { * this.val = (val===undefined ? 0 : val) * this.left = (left===undefined ? null : left) * this.right = (right===undefined ? null : right) * } */
/** * @param {TreeNode} root * @return {number[][]} */
var levelOrder = function(root) {
if (!root) return []
const q = [ [root, 0] ]
const res = []
while(q.length) {
const [n, level] = q.shift()
if (!res[level]) {
res.push([n.val])
} else {
console.log(res, level)
res[level].push(n.val)
}
if (n.left) q.push([n.left, level + 1])
if (n.right) q.push([n.right, level + 1])
}
return res
};
复制代码
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
来源:力扣(LeetCode)
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var inorderTraversal = function(root) {
const res = []
const rec = n => {
if (!root) return
rec(n.left)
res.push(n.val)
rec(n.right)
}
rec(root)
return res
};
复制代码
输入: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出: true
复制代码
输入:root = [1,2,3], targetSum = 5
输出:false
示例 3:
输入:root = [1,2], targetSum = 0
输出:false
来源:力扣(LeetCode)
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} targetSum
* @return {boolean}
*/
var hasPathSum = function(root, targetSum) {
if (!root) return false;
let res = false
const dfs = (n, s) => {
if (!n.left && !n.right && s === targetSum) {
res = true
}
if (n.left) dfs(n.left, s + n.left.val)
if (n.right) dfs(n.right, s + n.right.val)
}
dfs(root, root.val)
return res
};
复制代码
const json = {
a: { b: { c: 1 } } ,
d: [1, 2]
}
const dfs = (n, path) => {
if (!n) return
console.log(n, path)
Object.keys(n).forEach(k => {
dfs(n[k], path.concat(k))
})
}
dfs(json, [])
复制代码
总结:this
- 树 是一种分层的数据抽象模型
- 树的经常使用操做:深度/广度优先遍历、先中后序遍历...