二叉树之先序、中序、后序遍历,递归与非递归实现

今天学习了二叉树的遍历,以此方式加深印象。
上图

  • 定义Node
public static class Node {
		int value; //节点值
		public Node left; //左节点
		public Node right; //右节点
		public Node(int value) {
			this.value = value;
		}
	}

- 先序遍历

定义:按根左右的顺序进行遍历

  • 递归方式实现
public static void preOrderRecur(Node head) {
		if (head == null) {
			return;
		}
		System.out.print(head.value + " ");
		preOrderRecur(head.left);
		preOrderRecur(head.right);
	}
  • 非递归方式实现
public static void preOrderUnRecur(Node head) {
		System.out.print("pre-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<>();
			stack.push(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 inOrderRecur(Node head) {
		if (head == null) {
			return;
		}
		inOrderRecur(head.left);
		System.out.print(head.value + " ");
		inOrderRecur(head.right);
	}
  • 非递归方式实现
public static void inOrderUnRecur(Node head) {
		System.out.print("in-order : ");
		if (head != null) {
			Stack<Node> stack = new Stack<>();
			while (!stack.isEmpty() || head != null) {
				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 posOrderRecur(Node head) {
		if (head == null) {
			return;
		}
		posOrderRecur(head.left);
		posOrderRecur(head.right);
		System.out.print(head.value + " ");
	}
  • 非递归方式实现
//前面讲了先序遍历的非递归实现,后序遍历在其基础上稍作改变
public static void posOrderUnRecur(Node head) {
		System.out.print("pos-order: ");
		if (head != null) {
			Stack<Node> stack1 = new Stack<>();
			Stack<Node> stack2 = new Stack<>();
			stack1.push(head); //压入栈中
			while (!stack1.isEmpty()) {
				head = stack1.pop(); //将其弹出并压入stack2中
				stack2.push(head);
				// 压入stack1后还要弹出并压入stack2
				// 因此先压入左节点再压入右节点
				// 从stack2中弹出时则为左右根
				if (head.left != null) {
					stack1.push(head.left);
				}
				if (head.right != null) {
					stack1.push(head.right);
				}
			}
			while (!stack2.isEmpty()) { //打印stack2中弹出的节点值
				System.out.print(stack2.pop().value + " ");
			}
		}
		System.out.println();
	}
  • 测试
public static void main(String[] args) {
		Node head = new Node(5);
		head.left = new Node(3);
		head.left.left = new Node(2);
		head.left.left.left = new Node(1);
		head.left.right = new Node(4);
		head.right = new Node(8);
		head.right.left = new Node(7);
		head.right.left.left = new Node(6);
		head.right.right = new Node(10);
		head.right.right.left = new Node(9);
		head.right.right.right = new Node(11);

		System.out.println("===========recursive==========");
		System.out.print("pre-order: ");
		preOrderRecur(head);
		System.out.println();
		System.out.print("in-order: ");
		inOrderRecur(head);
		System.out.println();
		System.out.print("pos-order: ");
		posOrderRecur(head);
		System.out.println();

		System.out.println("===========unrecursive=========");
		preOrderUnRecur(head);
		inOrderUnRecur(head);
		posOrderUnRecur(head);
	}
  • 结果
===========recursive==========
pre-order: 5 3 2 1 4 8 7 6 10 9 11 
in-order : 1 2 3 4 5 6 7 8 9 10 11 
pos-order: 1 2 4 3 6 7 9 11 10 8 5 
===========unrecursive=========
pre-order: 5 3 2 1 4 8 7 6 10 9 11 
in-order : 1 2 3 4 5 6 7 8 9 10 11 
pos-order: 1 2 4 3 6 7 9 11 10 8 5 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值