前言
前序、中序、后序方式可以使用递归和非递归方式,这里将都一一举例,层次遍历时有两种方法,第一种方法只是简单的遍历出来,第二种方法是用一个集合将他每层内容包含,作用是让它分了组,可以知道是第几层。
值得注意的是:我是先将每一个方法先单独写出来,最后附上完整的代码(所有方式都有哦)想先知道结果的可以直接复制先测试。
我们测试的树图片:

前序遍历
首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。
前序遍历:ABDEGCF
递归方式
//递归前序遍历 根左右
private static void preOrder(TreeNode root){
System.out.print(root.val);
if (root.left!=null) preOrder(root.left);
if (root.right!=null) preOrder(root.right);
}
非递归方式
通过栈来实现。
//非递归前序遍历 根左右
private static void preOrder1(TreeNode root){
if (root==null)return;
Stack<TreeNode>stack=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node =stack.pop();
System.out.print(node.val);
//因为是一个栈,先进后出,所以右子结点先进入栈,在左子结点进入
if (node.right!=null) stack.push(node.right);
if (node.left!=null) stack.push(node.left);
}
}
中序遍历
中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。若二叉树为空则结束返回,否则: 1.中序遍历左子树
2.访问根结点 3.中序遍历右子树
中序遍历:DBGEACF
递归方式
//递归中序遍历 左根右
private static void midOrder(TreeNode root){
//直到找到最左边的结点才输出,即:D结点
if (root.left!=null) midOrder(root.left);
System.out.print(root.val);
if (root.right!=null) midOrder(root.right);
}
非递归方式
通过栈来实现。
//非递归中序遍历
private static void midOrder1(TreeNode root){
if (root==null)return;
Stack<TreeNode>stack=new Stack<>();
//创建一个中间节点,保存树中节点值
TreeNode node1=root;
//两个条件栈不为空,和中间结点不为空,二者满足其一即可
while (!stack.isEmpty()||node1!=null){
while(node1!=null){
stack.push(node1);
//一直往左边找,有就把它压入栈中,当没有时node1=null
node1=node1.left;
}
//当没有node1=null时,打印出当前栈顶元素
TreeNode node2=stack.pop();
System.out.print(node2.val);
//查看node2是否右子结点有值
if (node2.right!=null)node1=node2.right;
}
}
后序遍历
首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。
后序遍历:DGEBFCA
递归方式
//递归后序遍历 左右根
private static void postOrder(TreeNode root){
if (root.left!=null) postOrder(root.left);
if (root.right!=null) postOrder(root.right);
System.out.print(root.val);
}
非递归方式
前序遍历是: 根左右 调换左右子结点进栈位置为: 根右左
在通过输入一个新栈中,在输出来就是:左右根(栈先进后出)
//非递归后序遍历 左右根
private static void postOrder1(TreeNode root){
if (root==null)return;
Stack<TreeNode>stack=new Stack<>();
//新栈:答案的逆序
Stack<TreeNode>stack2=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node =stack.pop();
//将值压入新栈
stack2.push(node);
//调换了左右子结点进栈的位置
if (node.left!=null) stack.push(node.left);
if (node.right!=null) stack.push(node.right);
}
//输出新栈的内容
while (!stack2.isEmpty()){
System.out.print(stack2.pop().val);
}
}
层序遍历
二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推
遍历方法:层序遍历是通过一个队列来实现的,先让根节点入队,当根节点出队的时候,看是否有左右子结点,有就让其入队,之后就是判断当前要出队的结点是否有左右子结点,有就入队,没有就继续输出队首元素。

层序遍历方式一
层序遍历方式一:ABCDEFG
//层序遍历方式一
private static void dfs(TreeNode root){
if (root==null)return;
//队列
Queue<TreeNode>queue=new LinkedList<>();
//当前结点入队
queue.add(root);
while(!queue.isEmpty()){
//队列首元素出队
TreeNode node1=queue.poll();
System.out.print(node1.val);
//判断是否有左右子结点,有就入队
if (node1.left!=null)queue.add(node1.left);
if (node1.right!=null)queue.add(node1.right);
}
}
层序遍历方式 二
层序遍历方式二(分组输出):[A][B, C][D, E, F][G]
//层序遍历方式二
private static List<List<String>> dfs2(TreeNode root){
//保存temp的内容,输出是三个集合List <String>,起到分组的作用
List<List<String>>res=new ArrayList<>();
//队列
Queue<TreeNode>queue=new LinkedList<>();
queue.add(root);
//用List <String>temp保存每一层的结果
List <String>temp;
while(!queue.isEmpty()){
int size=queue.size();
temp=new ArrayList<>();
while (size-->0){
TreeNode node1=queue.poll();
temp.add(node1.val);
if (node1.left!=null)queue.add(node1.left);
if (node1.right!=null)queue.add(node1.right);
}
res.add(temp);
}
return res;
}
完整代码
package tree;
import java.util.*;
@SuppressWarnings("all")//抑制警告(主要是自己不想看到哈哈)
public class My_tree {
public static void main(String[] args) {
//这一部分是创建结点并且设置好他们的左右结点
TreeNode nodeA=new TreeNode("A");
TreeNode nodeB=new TreeNode("B");
TreeNode nodeC=new TreeNode("C");
TreeNode nodeD=new TreeNode("D");
TreeNode nodeE=new TreeNode("E");
TreeNode nodeF=new TreeNode("F");
TreeNode nodeG=new TreeNode("G");
nodeA.left=nodeB;
nodeA.right=nodeC;
nodeB.left=nodeD;
nodeB.right=nodeE;
nodeE.left=nodeG;
nodeC.right=nodeF;
System.out.print("递归前序遍历:");
preOrder(nodeA);
System.out.println();
System.out.print("递归中序遍历:");
midOrder(nodeA);
System.out.println();
System.out.print("递归后序遍历:");
postOrder(nodeA);
System.out.println();
System.out.print("非递归前序遍历:");
preOrder1(nodeA);
System.out.println();
System.out.print("非递归中序遍历:");
midOrder1(nodeA);
System.out.println();
System.out.print("非递归后序遍历:");
postOrder1(nodeA);
System.out.println();
System.out.print("层序遍历方式一:");
dfs(nodeA);
System.out.println();
System.out.print("层序遍历方式二(分组输出):");
//打印返回集合里面的东西
List<List<String>> list= dfs2(nodeA);
for (int i = 0; i <4; i++) {
System.out.print(list.get(i));
}
}
//递归前序遍历 根左右
private static void preOrder(TreeNode root){
System.out.print(root.val);
if (root.left!=null) preOrder(root.left);
if (root.right!=null) preOrder(root.right);
}
//非递归前序遍历 根左右
private static void preOrder1(TreeNode root){
if (root==null)return;
Stack<TreeNode>stack=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node =stack.pop();
System.out.print(node.val);
//因为是一个栈,先进后出,所以右子结点先进入栈,在左子结点进入
if (node.right!=null) stack.push(node.right);
if (node.left!=null) stack.push(node.left);
}
}
//递归中序遍历 左根右
private static void midOrder(TreeNode root){
//直到找到最左边的结点才输出,即:D结点
if (root.left!=null) midOrder(root.left);
System.out.print(root.val);
if (root.right!=null) midOrder(root.right);
}
//非递归中序遍历
private static void midOrder1(TreeNode root){
if (root==null)return;
Stack<TreeNode>stack=new Stack<>();
//创建一个中间节点,保存树中节点值
TreeNode node1=root;
//两个条件栈不为空,和中间结点不为空,二者满足其一即可
while (!stack.isEmpty()||node1!=null){
while(node1!=null){
stack.push(node1);
//一直往左边找,有就把它压入栈中,当没有时node1=null
node1=node1.left;
}
//当没有node1=null时,打印出当前栈顶元素
TreeNode node2=stack.pop();
System.out.print(node2.val);
//查看node2是否右子结点有值
if (node2.right!=null)node1=node2.right;
}
}
//递归后序遍历 左右根
private static void postOrder(TreeNode root){
if (root.left!=null) postOrder(root.left);
if (root.right!=null) postOrder(root.right);
System.out.print(root.val);
}
//非递归后序遍历 左右根
//前序遍历是: 根左右 调换左右子结点进栈位置为: 根右左
//在通过输入一个新栈中,在输出来就是:左右根(栈先进后出)
private static void postOrder1(TreeNode root){
if (root==null)return;
Stack<TreeNode>stack=new Stack<>();
//新栈:答案的逆序
Stack<TreeNode>stack2=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node =stack.pop();
//将值压入新栈
stack2.push(node);
//调换了左右子结点进栈的位置
if (node.left!=null) stack.push(node.left);
if (node.right!=null) stack.push(node.right);
}
//输出新栈的内容
while (!stack2.isEmpty()){
System.out.print(stack2.pop().val);
}
}
//层序遍历方式一
private static void dfs(TreeNode root){
if (root==null)return;
//队列
Queue<TreeNode>queue=new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
TreeNode node1=queue.poll();
System.out.print(node1.val);
if (node1.left!=null)queue.add(node1.left);
if (node1.right!=null)queue.add(node1.right);
}
}
//层序遍历方式二
private static List<List<String>> dfs2(TreeNode root){
List<List<String>>res=new ArrayList<>();
//队列
Queue<TreeNode>queue=new LinkedList<>();
queue.add(root);
List <String>temp;
while(!queue.isEmpty()){
int size=queue.size();
temp=new ArrayList<>();
while (size-->0){
TreeNode node1=queue.poll();
temp.add(node1.val);
if (node1.left!=null)queue.add(node1.left);
if (node1.right!=null)queue.add(node1.right);
}
res.add(temp);
}
return res;
}
}
//定义一个类,包含它的值和左右结点
class TreeNode {
String val;
public TreeNode left;
public TreeNode right;
//空参构造方法,赋予当前结点值
public TreeNode(String val) {
this.val = val;
}
}
完整代码运结果

本文详细介绍了二叉树的前序、中序、后序及层次遍历方法,包括递归与非递归实现,并提供了完整的代码示例。
1403

被折叠的 条评论
为什么被折叠?



