二叉树是什么
树中的每个节点最多只能有两个子节点
在js中通常用Object来模拟二叉树
递归版的先中后序遍历
(一)先序遍历算法
访问根节点
对根节点的左子树进行先序遍历
对根节点的右子树进行先序遍历
function preorder (node) {
if (!node) return;
console.log(node.val)
preorder(node.left)
preorder(node.right)
}
(二)中序遍历算法
左右根
function inorder (node) {
if (!node) return;
inorder(node.left)
console.log(node.val)
inorder(node.right)
}
(三)后序遍历算法
左右根
function postorder (node) {
if (!node) return;
postorder(node.left)
postorder(node.right)
console.log(node.val)
}
非递归版的先中后序遍历
用堆栈模拟递归的操作
(一)先序遍历
思路:
根节点入栈
while(栈不为空) :
- 栈顶出栈访问 ;
- 右左子节点入栈 ; //注意 : 栈是先进后出,所以右结点先入栈
function 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) }
}
}
(二)中序遍历
思路:
while(栈非空 || 指针非空):
- all的左子树入栈; //包括根节点
- 出栈访问;
- 指针指向右结点
function inOrder (root) {
if (!root) return;
const stack = []
let p = root;
while (stack.length || p) {
while (p) {
stack.push(p)
p = p.left
}
const n = stack.pop()
console.log(n.val)
p = n.right;
}
}
(三)后序遍历
左右根
解题思路:
把左右根倒过来就是根右左 ,这就类似先序遍历了 ,由于先序遍历是根左右,
后序遍历倒置是根右左,所以需要对先序遍历稍加修改。
解题步骤:
初始化两个空栈stack1 stack2;
使用stack1对二叉树进行先序遍历:
- 这里的出栈访问操作改为出栈1入栈2;
- 由于是根右左,所以子节点的入栈顺序应为左右节点依次入栈;
stack2依次出栈访问;
function preOrder (root) {
if (!root) return;
const stack = [root];
const res = []
while (stack.length) {
const n = stack.pop()
res.push(n)
if (n.left) { stack.push(n.left) }
if (n.right) { stack.push(n.right) }
}
while (res.length) {
console.log(res.pop().val)
}
}
LeetCode 104. 二叉树的最大深度
给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回它的最大深度 3 。
- 基础知识: 树的深度遍历如何实现?
即先序遍历,先访问根节点,再对左子树深度遍历,最后对右子树深度遍历 - 解题思路:
① 初始化res为-1,表示当前的最深层次;
② 对二叉树进行深度遍历:
每遍历到一个叶子节点就计算一下res;(当前层次与res 比较,取较大)
每次递归将被递归节点的层级一起传值 - 复杂度分析:
每次递函数内调用函数,使用了调用堆栈,堆栈的大小为dfs嵌套的层数,即二叉树的最大深度
- 时间复杂度: o(n) //每个节点都遍历了一次 ,n是节点的个数
- 空间复杂度: 最坏o(n) ; 最好 o(logn) ,即平衡二叉树 ;
var maxDepth = function(root) {
function dfs(node,level){
if(!node) return ;
if(!node.left && !node.right){
res=Math.max(level,res);
return ;
}
if(node.left) dfs(node.left,level+1,res)
if(node.right) dfs(node.right,level+1,res)
}
if(!root) return 0;
let res=1;
dfs(root,1)
return res
};