Java二叉树递推遍历

引入

学习二叉树离不开访问遍历它,最简单的方法是递归遍历来实现,递归实现简单,但递推偏复杂些,我这用Java实现,做个笔记。

Java代码

  • DisPlayBinaryTree.java
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class DisPlayBinaryTree {
	/*
	先序思路:
	1.遇到一个节点,就访问它,并遍历它的左子树
	2.当左子树遍历完后,从栈顶弹出节点
	3.然后变换为它的右节点再去先序遍历该节点的子树
	*/
	// 1. 先序
	public void preorder(TreeNode curnode){
		Stack<TreeNode> stack = new Stack<>();
		while(curnode != null || !stack.isEmpty()){
			// 依次把左子树压入栈并访问当前节点
			while(curnode != null){
				System.out.print(curnode.val+" ");// 访问
				stack.push(curnode);
				curnode = curnode.leftNode;
			}
			// 遍历完左子树,弹出栈顶
			curnode = stack.pop();
			// 变换为它的右节点继续先序遍历
			curnode = curnode.rightNode;
		}
	}
	/*
	中序思路:(与先序思路差不多)
	1.遇到一个节点,就把它压入栈,并遍历它的左子树
	2.当左子树遍历完后,从栈顶弹出节点并访问它
	3.然后变换为它的右节点再去中序遍历该节点的子树
	*/
	public void midorder(TreeNode curnode){
		Stack<TreeNode> stack = new Stack<>();
		while(curnode != null || !stack.isEmpty()){
			// 依次把左子树压入栈
			while(curnode != null){
				stack.push(curnode);
				curnode = curnode.leftNode;
			}
			// 遍历完左子树,弹出栈顶并访问
			curnode = stack.pop();
			System.out.print(curnode.val+" ");
			// 变换为它的右节点继续中序遍历
			curnode = curnode.rightNode;
		}
	}
	/*
	后序思路:(与前两者稍有不同,但框架差不多)
	1.遇到一个节点,把它压入栈,并遍历它的左子树
	2.当左子树遍历后,从栈顶弹出节点,判断是否输出的时刻(自己没有右节点,或者,自己的右节点被访问过了就输出继续2步骤,否则进入3)
	3.把这弹出的节点再次入栈,变换为它的右节点再继续后序遍历该节点的子树
	*/
	public void lastorder(TreeNode curnode){
		Stack<TreeNode> stack = new Stack<>();
		TreeNode lastnode = null;// 记录上一次访问的节点
		while(curnode != null || !stack.isEmpty()){
			// 依次把左子树压入栈
			while(curnode != null){
				stack.push(curnode);
				curnode = curnode.leftNode;
			}
			// 遍历完左子树,弹出栈顶
			curnode = stack.pop();
			// 当前节点可以输出条件:它的右节点为空,或者,它从它的右节点返回回来
			if(curnode.rightNode == null || curnode.rightNode == lastnode){
				System.out.print(curnode.val+" ");
				lastnode = curnode;
				curnode = null;// 访问完就置空了,免得再次把它的左子树压入栈
			}else{
				// 没到访问时机,再次把这节点压入栈
				stack.push(curnode);
				// 变化为它的右节点,继续后序遍历
				curnode = curnode.rightNode;
			}
		}
	}
	
	public static void main(String[] args) {
		// 构建树结构
		TreeNode root = new TreeNode(9);
		TreeNode node1 = new TreeNode(13);
		TreeNode node2 = new TreeNode(17);
		TreeNode node3 = new TreeNode(45);
		TreeNode node4 = new TreeNode(53);
		TreeNode node5 = new TreeNode(32);
		TreeNode node6 = new TreeNode(46);
		TreeNode node7 = new TreeNode(65);
		TreeNode node8 = new TreeNode(78);
		TreeNode node9 = new TreeNode(87);
		root.leftNode = node1;
		root.leftNode.leftNode = node2;
		root.leftNode.rightNode = node3;
		root.leftNode.leftNode.leftNode = node4;
		root.leftNode.leftNode.rightNode = node5;
		root.leftNode.rightNode.leftNode = node6;

		root.rightNode = node7;
		root.rightNode.leftNode = node8;
		root.rightNode.rightNode = node9;
		DisPlayBinaryTree dt = new DisPlayBinaryTree();
		System.out.print("先序遍历:");// 先序遍历
		dt.preorder(root);
		System.out.println();
		
		System.out.print("中序遍历:");// 中序遍历
		dt.midorder(root);
		System.out.println();
		
		System.out.print("后序遍历:");// 后序遍历
		dt.lastorder(root);
		System.out.println();
		
		System.out.print("层次遍历:");// 层次遍历
		dt.levelorder(root);
	}
	
	/*
	补一个,用队列层次遍历
	1.先读取队列的队首节点,并且访问它
	2.把它的左右节点添加到队列中
	*/
	public void levelorder(TreeNode curnode){
		Queue<TreeNode> que = new LinkedList<TreeNode>();
		que.add(curnode);
		while(!que.isEmpty()){
			curnode = que.poll();
			System.out.print(curnode.val+" ");
			if(curnode.leftNode != null){
				que.add(curnode.leftNode);
			}
			if(curnode.rightNode != null){
				que.add(curnode.rightNode);
			}
		}
	}
}

  • TreeNode.java
public class TreeNode {
	TreeNode leftNode;
	TreeNode rightNode;
	int val;
	
	public TreeNode() {
		// TODO Auto-generated constructor stub
	}
	public TreeNode(int vl) {
		// TODO Auto-generated constructor stub
		this.val = vl;
	}
	public TreeNode getLeftNode() {
		return leftNode;
	}

	public void setLeftNode(TreeNode leftNode) {
		this.leftNode = leftNode;
	}

	public TreeNode getRightNode() {
		return rightNode;
	}

	public void setRightNode(TreeNode rightNode) {
		this.rightNode = rightNode;
	}

	public int getVal() {
		return val;
	}

	public void setVal(int val) {
		this.val = val;
	}
}

构造的二叉树
在这里插入图片描述
程序运行结果
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘建杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值