1.什么是二叉树
1.1直观表示如图所示,如树的枝叶式发散,有根节点,有叶子节点
1.2 用js代码表示
const tree = {
val:7,
left:{
val:4,
left:{
val:1
},
right:{
val:3,
left:{
val:2
}
}
},
right:{
val:6,
right:{
val:5
}
}
}
2.深度遍历/广度遍历
2.1.1什么是深度遍历
尽可能深的搜索树的分支
2.1.2代码实现深度遍历
”尽可能深“ 我们可以联想到递归,不断往内访问 就以上面js定义的二叉树结构为入参,来实现对该入参的深度遍历
function dfs(tree){
if(!tree) return
console.log(tree.val);
if(tree.left) dfs(tree.left)
if(tree.right) dfs(tree.right)
}
dfs(tree) // 7 4 1 3 2 6 5
2.2.1什么是广度遍历
优先访问离根节点最近的节点
2.2.2代码实现广度遍历
function bfs(tree){
if(!tree) return
const stack = [tree]
while (stack.length) {
const head = stack.shift()
console.log(head.val);
if (head.left) stack.push(head.left)
if(head.right) stack.push(head.right)
}
}
bfs(tree) // 7 4 6 1 3 5 2
3.先中后序遍历
以下代码实现均选1.2中的树结构作为入参参考实现。重点关注实现思想
3.1.1什么是先序遍历
先序遍历: 1.访问根节点 2.对根节点的左子树进行先序遍历 3.对根节点的右子树进行先序遍历 总结就是访问顺序:根->左->右
3.1.2代码实现(递归及非递归版)
// 递归实现
function preorder(tree){
if(!tree) return
console.log(tree.val);
if(tree.left) preorder(tree.left)
if(tree.right) preorder(tree.right)
}
// 非递归版
function preorder(tree){
if(!tree) return
const stack = [ tree ]
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)
}
}
3.2.1什么是中序遍历
中序遍历: 1.对根节点的左子树进行中序遍历 2.访问根节点 3.对根节点的右子树进行中序遍历 总结就是访问顺序:左->根->右
3.2.2代码实现(递归及非递归版)
// 递归版
function inorder(tree){
if(!tree) return
if(tree.left) inorder(tree.left)
console.log(tree.val);
if(tree.right) inorder(tree.right)
}
// 非递归版
function inorder(tree){
if(!tree) return
const stack = [] // 执行栈
let p = tree // 全局指针
while(stack.length || p){
while(p){
stack.push(p)
p = p.left
}
const n = stack.pop()
console.log(n.val);
p = n.right
}
}
3.3.1什么是后序遍历
后序遍历: 1.对左子树进行后序遍历 2.对右子树进行后序遍历 3.访问根节点 总结:左->右->根
3.3.2代码实现(递归及非递归版)
// 递归版
function postorder(tree){
if(!tree) return
if(tree.left) postorder(tree.left)
if(tree.right) postorder(tree.right)
console.log(tree.val);
}
// 非递归版
function postorder(tree){
if(!tree) return
const stack = [tree]
const outStack = []
while (stack.length) {
const n = stack.pop()
outStack.push(n)
if(n.left) stack.push(n.left)
if(n.right) stack.push(n.right)
}
while(outStack.length){
const m = outStack.pop()
console.log(m.val);
}
}
postorder(tree)
4.求二叉树最大深度
如图所示,最大深度为4,访问路径是:7->4->3->2
代码实现:
function maxDepth(tree){
let res = 0
function dfs(root,level){ // 深度遍历
// level标记当前所处的层级
if(!root.left && !root.right){
// 只有叶子节点才进行计算,提高运算速度
res = Math.max(res,level)
}
if(root.left) dfs(root.left,level+1)
if(root.right) dfs(root.right,level+1)
}
dfs(tree,1)
return res
}
5.求二叉树路径之和
如下图所示的路径有三条,各路径之和(从左到右)分别为: 12 16 18
代码实现:
function depthSum(tree){
if(!tree) return
function dfs(root,sum){
if(!root.left && !root.right){
console.log(sum);
}
if(root.left) dfs(root.left,sum + root.left.val)
if(root.right) dfs(root.right,sum + root.right.val)
}
dfs(tree,tree.val)
}