二叉树1:实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式

本文介绍了二叉树的三种遍历方式:先序、中序和后序遍历,并详细阐述了递归与非递归的实现方法。通过理解递归实质与掌握非递归技巧,有助于深入理解二叉树操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉树的先序遍历:
1:访问根节点
2:访问左子树
3:访问右子树
在这里插入图片描述
二叉树的中序遍历:
1:中序遍历左子树
2:访问根节点
3:中序遍历右子树
在这里插入图片描述
二叉树的后序遍历:
1:后序遍历左子树
2:后序遍历右子树
3:访问根节点
在这里插入图片描述
使用递归的方式来实现二叉树的几种遍历:

public class Code_01_PreInPosTraversal {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int data) {
			this.value = data;
		}
	}

	public static void preOrderRecur(Node head) { //递归的方式 先序遍历
		if (head == null) {
			return;
		}
		System.out.print(head.value + " ");
		preOrderRecur(head.left);
		preOrderRecur(head.right);
	}

	public static void inOrderRecur(Node head) { // 递归的方式 中序遍历
		if (head == null) {
			return;
		}
		inOrderRecur(head.left);
		System.out.print(head.value + " ");
		inOrderRecur(head.right);
	}

	public static void posOrderRecur(Node head) { //递归的方式 后序遍历
		if (head == null) {
			return;
		}
		posOrderRecur(head.left);
		posOrderRecur(head.right);
		System.out.print(head.value + " ");
	}

这里的return返回是此函数的结束处,相应的变量的参数也会返回到上一层的参数处,覆盖原来的参数,继续此函数之后未完成的函数动作,如果此函数执行完则跳出此层递归,继续返回上次未完成的函数处(递归调用处)。
理解一下递归的实质:

使用非递归的方法:在这里插入图片描述
注意return:return的时候代表这个子函数已经执行完毕了,使用再执行的是下一个栈元素

import java.util.Stack;

public class Code_01_PreInPosTraversal {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int data) {
			this.value = data;
		}
	}

	public static void preOrderRecur(Node head) { //递归的方式 先序遍历
		if (head == null) {
			return;
		}
		System.out.print(head.value + " ");
		preOrderRecur(head.left);
		preOrderRecur(head.right);
	}

	public static void inOrderRecur(Node head) { // 递归的方式 中序遍历
		if (head == null) {
			return;
		}
		inOrderRecur(head.left);
		System.out.print(head.value + " ");
		inOrderRecur(head.right);
	}

	public static void posOrderRecur(Node head) { //递归的方式 后序遍历
		if (head == null) {
			return;
		}
		posOrderRecur(head.left);
		posOrderRecur(head.right);
		System.out.print(head.value + " ");
	}

	public static void preOrderUnRecur(Node head) { //先序遍历 非递归
		System.out.print("pre-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.add(head);
			while (!stack.isEmpty()) { 
				head = stack.pop();
				System.out.print(head.value + " ");
				if (head.right != null) {  //先序遍历要先把右边的压入栈中
					stack.push(head.right);
				}
				if (head.left != null) {
					stack.push(head.left);
				}
			}
		}
		System.out.println();
	}

	public static void inOrderUnRecur(Node head) { //中序遍历 非递归
		System.out.print("in-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			while (!stack.isEmpty() || head != null) { //这个条件是当head在最高的节点时和head的左边为空时这个边界
				if (head != null) {  //把左边的节点依次压入栈中
					stack.push(head);
					head = head.left;
				} else {
					head = stack.pop(); //左边已经为空了,弹出,看右边有没有节点
					System.out.print(head.value + " ");
					head = head.right;
				}
			}
		}
		System.out.println();
	}

	public static void posOrderUnRecur1(Node head) { //后序遍历 非递归 使用两个栈
		System.out.print("pos-order: ");
		if (head != null) {
			Stack<Node> s1 = new Stack<Node>();
			Stack<Node> s2 = new Stack<Node>();//用来存放按后序排序好的二叉树
			s1.push(head);
			while (!s1.isEmpty()) {
				head = s1.pop();
				s2.push(head);
				if (head.left != null) {
					s1.push(head.left); //放到栈S2时刚好左子树的在右子树的上面
				}
				if (head.right != null) {
					s1.push(head.right);
				}
			}
			while (!s2.isEmpty()) {
				System.out.print(s2.pop().value + " ");
			}
		}
		System.out.println();
	}

	public static void posOrderUnRecur2(Node h) {  //使用一个栈
		System.out.print("pos-order: ");
		if (h != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.push(h);
			Node c = null;
			while (!stack.isEmpty()) {
				c = stack.peek();//取出但不销毁,还是在原来的栈中
				if (c.left != null && h != c.left && h != c.right) {
					stack.push(c.left);
				} else if (c.right != null && h != c.right) { //防止一个节点被压入两次
					stack.push(c.right);
				} else {
					System.out.print(stack.pop().value + " ");
					h = c;
				}
			}
		}
		System.out.println();
	}

自己好好理解非递归,再自己敲一遍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值