二叉树的先,中,后序遍历(递归,非递归)
二叉树的先,中,后序遍历(递归,非递归)
作者:Grey
原文地址:
说明#
本文主要介绍了二叉树的先序,中序,后序遍历。并且分别用如下两种方式实现:
-
递归方法
-
非递归(使用栈)
示例二叉树#
数据结构#
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
先序遍历#
先序遍历流程#
先头,再左,再右。
示例中的二叉树,先序遍历的结果为:
1-->2-->4-->7-->11-->8-->12-->3-->5-->6-->9-->13-->10
递归方法实现先序遍历#
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
pre(root, ans);
return ans;
}
public void pre(TreeNode root, List<Integer> ans) {
if (root == null) {
return;
}
ans.add(root.val);
pre(root.left, ans);
pre(root.right, ans);
}
使用栈实现先序遍历#
流程如下:
第一步,申请一个栈,并把头节点压入;
第二步,弹出就收集答案;
第三步,第二步中弹出的节点,如果右孩子不为空,则右孩子入栈;
第四步,第二步中弹出的节点,如果左孩子不为空,则左孩子入栈;
第五步,循环执行第二步到第四步,直到栈为空。
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if (null == root) {
return ans;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
ans.add(node.val);
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
return ans;
}
测评链接:LeetCode 144. Binary Tree Preorder Traversal
中序遍历#
中序遍历流程#
先中,再左,再右。
示例中的二叉树,中序遍历的结果为:
2-->11-->7-->4-->12-->8-->1-->5-->3-->9-->13-->6-->10
递归方法实现中序遍历#
public List<Integer> inorderTraversal(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
List<Integer> ans = new ArrayList<>();
in(root, ans);
return ans;
}
private void in(TreeNode root, List<Integer> ans) {
if (root == null) {
return;
}
in(root.left, ans);
ans.add(root.val);
in(root.right, ans);
}
使用栈实现中序遍历#
也是申请一个栈,有如下几个步骤:
第一步,整条左边界入栈。
第二步,弹出就收集答案。
第三步,来到右树上执行同第一步的操作。
第四步,直到栈为空。
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if (null == root) {
return ans;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (!stack.isEmpty() || cur != null) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
TreeNode node = stack.pop();
ans.add(node.val);
cur = node.right;
}
}
return ans;
}
测评链接:LeetCode 94. Binary Tree Inorder Traversal
后序遍历#
后序遍历流程#
先左,后右,再中。
示例中的二叉树,后序遍历的结果为:
11-->7-->12-->8-->4-->2-->5-->13-->9-->10-->6-->3-->1
递归方法实现后序遍历#
public List<Integer> postorderTraversal(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
List<Integer> ans = new ArrayList<>();
pos(root, ans);
return ans;
}
public void pos(TreeNode root, List<Integer> ans) {
if (root == null) {
return;
}
pos(root.left, ans);
pos(root.right, ans);
ans.add(root.val);
}
使用两个栈实现后序遍历#
由于我们已经可以通过栈来实现先序遍历,即:先头,再左,再右。
而后序遍历的流程是:先左,再右,再头。
所以我们可以通过先序遍历的代码简单加工得到后序遍历的代码。
首先,我们先通过先序遍历的代码,将先序遍历加工成:先头,再右,再左。
把这个结果放入一个栈中,然后将这个栈中的内容依次弹出,便是后序遍历的结果。
public List<Integer> postorderTraversal2(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
List<Integer> ans = new ArrayList<>();
Stack<TreeNode> helper = new Stack<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
stack.push(cur);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
// 先存一个栈里面
helper.push(node);
// 先序遍历的时候,是先判断右树,改造一下,先判断左树
if (node.left != null) {
cur = node.left;
stack.push(cur);
}
if (node.right != null) {
cur = node.right;
stack.push(cur);
}
}
while (!helper.isEmpty()) {
ans.add(helper.pop().val);
}
return ans;
}
测评链接:LeetCode 145. Binary Tree Postorder Traversal
更多#
作者:GreyZeng
出处:https://www.cnblogs.com/greyzeng/p/15941957.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
你可以在这里自定义其他内容
本文来自博客园,作者:Grey Zeng,转载请注明原文链接:https://www.cnblogs.com/greyzeng/p/15941957.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2021-02-27 JavaSE实现IoC