二叉树遍历方法合集:
最近在LeetCode力扣上刷数据结构的二叉树合集,遇到的二叉树遍历方法,于是想理解透彻。本文讲解了二叉树遍历的四种方法,前、中。后序遍历。
对应题目:
94.二叉树的中序遍历
144.二叉树的前序遍历
145.二叉树的后序遍历
102.二叉树的层序遍历
只要参考任意一种解法的代码,将其中的输出代码替换成添加数组元素即可。
我的本意是想让大家能深入的理解二叉树遍历的过程,之后完成这三道题和其它二叉树遍历的题目能够感觉轻松一点。
递归解法
递归解法是比较常用而且容易理解的方法,只要理解了思路就能够很好的去使用他。
**比如前序遍历:**前序遍历的递归方法就是:根、左、右,先打印根节点,只有再去寻找他的左子树,左子树找到末尾的时候返回再找又指数,直到完成。
下面放代码:
前序遍历
public static void PreOrderRecur(TreeNode root){
if(root == null) return;
System.out.println(root.data);
PreorderRecur(root.left);
PreorderRecur(root.right);
}
中序遍历
public static void InOrderRecur(TreeNode root){
if(root == null) return;
InorderRecur(root.left);
System.out.println(root.data);
InorderRecur(root.right);
}
后序遍历
public static void PostOrderRecur(TreeNode root){
if(root == null) return;
PostorderRecur(root.left);
PostorderRecur(root.right);
System.out.println(root.data);
}
观察可以发现,递归的实现其实只是输出根节点的位置不一样,并没有很大的不同。
迭代解法
本质上是在模拟递归,因为在递归的过程中使用了系统栈,所以在迭代的解法中常用Stack来模拟系统栈。注意栈的先进后出顺序,输出出来的就是倒序打印。
前序遍历
⼆叉树的前序遍历顺序是根-左-右。我们可以采⽤⼀个栈来辅助,我们把先序遍历的结果放到⼀个ArrayList 容器中作为返回值,具体步骤如下:
1、把⼆叉树的根节点 root 放进栈。
2、如果栈不为空,从栈中取出⼀个节点,把该节点放⼊容器的尾部;如果该节点的右⼦树不为空,则
把有节点放⼊栈;如果该节点的左⼦树不为空,则把左⼦树放⼊栈中。
3、⼀直重复步骤 2 ,直到栈为空,此时遍历结束,代码如下:
static List<Interger> PreOrderTraversal(TreeNode root){
List(Interger) result = new ArrayList<>();
Stack<TreeNode> stack = new Stack();
if(root == null) return result;
stack.push(root);//首先把根节点放入栈中
while(!stack.isEmpty(){
//当栈中不为空的时候,执行以下操作
TreeNode temp = stack.pop();//取出栈中的节点,用一个临时变量保存
result.add(temp.val);//将变量的值加入结果队列中
if(tmp.right!=null)
stack.push(root.right);//如果该节点的右⼦树不为空,则把有节点放⼊栈
if(tmp.left!=null)
stack.push(root.left);//如果该节点的左⼦树不为空,则把左⼦树放⼊栈中。
}
return result;
}
中序遍历
⼆叉树的中序遍历顺序是左-根-右。我们可以采⽤⼀个栈来辅助,我们把中序遍历的结果放到⼀个
ArrayList 容器中作为返回值,具体步骤如下:
1、进⼊ while 循环,接着把根节点及其所有左⼦节点放⼊栈中。
2、从栈中取出⼀个节点,把该节点放⼊容器的尾部;如果该节点的右⼦节点不为空,则把右⼦节点及
其右⼦节点的所有左⼦节点放⼊队列。
3、⼀直重复步骤 2 ,直到栈为空并且当前节点也为空则退出循环。
可能看解释反⽽有点乱,直接看代码吧,配合代码就容易懂了
代码如下:
public List<Integer> InOrderTraversal(TreeNode root){
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty())
{
if(root != null){
stack.push(root);
root=root.left;
}
else{
root = stack.pop();
res.add(root.data);
root=root.right;
}
}
return res;
}
后续遍历
宽搜+逆序输出 = 后序遍历
⼆叉树的后序遍历顺序是左-右-根。我们可以采⽤⼀个栈来辅助,不过它和前序遍历以及中序遍历还是有点区别的,我们把后序遍历的结果放到⼀个 LinkedList 容器中作为返回值,具体步骤如下:
1、把⼆叉树的根节点 root 放进栈。
2、如果栈不为空,从栈中取出⼀个节点,把该节点插⼊到容器的头部。;如果该节点的左⼦树不为
空,则把该左⼦树放⼊栈中;如果该节点的右⼦树不为空,则把右⼦树放⼊栈中。,
注意,之前的前序遍历和中序遍历,我们都是⽤ ArrayList 容器,并且是把节点插⼊到容器的尾部,这
就是后序遍历的不同点。
3、⼀直重复步骤 2 ,直到栈为空,此时遍历结束
代码如下:
public List<Integer> postOderTraversal(TreeNode root) {
LinkedList<Integer> res = new LinkedList<>();// 注意,采⽤链表
Stack<TreeNode> stack = new Stack<>();
if(root == null)
return res;
stack.push(root);
while (!stack.isEmpty()) {
TreeNode tmp = stack.pop();// 注意,是放在第⼀个位置
res.addFirst(tmp.val);
if(tmp.left != null)
stack.push(tmp.left);
if(tmp.right != null)
stack.push(tmp.right);
}
return res;
}