「 完结」二叉树问题(二叉树的前中后序的递归+非递归) java 《程序员代码面试指南》自学笔记 Chapter3-1


二叉树创建

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 if(head == null)
  • System.out.print(head.value + " ");
  • 引用函数:preOrderRecur(head.left);

中序

代码:

public static void inOrderRecur(Node head) {
	if(head == null) {
		return;
	}
	inOrderRecur(head.left);
	System.out.print(head.value +  " ");
	inOrderRecur(head.right);
}

后序

代码:

public static void postOrderRecur(Node head) {
	if(head == null) {
		return;
	}
	postOrderRecur(head.left);
	postOrderRecur(head.right);
	System.out.print(head.value + " ");
}

非递归

前序

代码:

public static void preOrderUnRecur(Node head) {
	if(head == null) {
		return;
	}
	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);
		}
	}
}

步骤:

  1. 压头 head 循环 (直到stack空):
  2. 弹栈顶+打印 cur
  3. 压右孩子 -左孩子

要点:

  • import java.util.Stack;

java.util.Stack类是继承了Vector类

  • Stack stack = new Stack();

<>代表泛型,Stack代表该Stack中只能放入NestedInteger类或者其子类的实例。去掉代表任何类型的对象都可放进去.
Stack表示一个栈。Stack表示一个栈,且栈里的每个元素都是T类型的。以此类推。
new表示调用该泛型类型的构造函数,创建一个实例。

  • stack.add(head);
  • stack.push(head.right);
  • head = stack.pop();

add & push
共同点:add,push都可以向stack中添加元素。
不同点:add是继承自Vector的方法,且返回值类型是boolean。push是Stack自身的方法,返回值类型是参数类类型。

  • while(!stack.isEmpty())
  • if(head.left != null)

中序

代码:

public static void inOrderUnRecur(Node head) {
	if(head != null) {
		Stack<Node> stack  = new Stack<Node>();
		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;
			}
		}			
	}
}

步骤:

循环(只要栈不空 或 头不空):

(如果头不空

  1. 压头
  2. 头=头的左孩子

(否则头空

  1. 弹栈顶+打印
  2. cur 头=头的右孩子

要点:

  • while(!stack.isEmpty() || head != null)

后序(两个栈)

代码

public static void postOrderUnRecur1(Node head) {
	if(head != null) {
		Stack<Node> stack1 = new Stack<Node>();
		Stack<Node> stack2 = new Stack<Node>();
		stack1.push(head);
		while(!stack1.isEmpty()) {
			head = stack1.pop();
			stack2.push(head);
			if(head.left != null) {
				stack1.push(head.left);
			}
			if(head.right != null) {
				stack1.push(head.right);
			}
		}
		
		while(!stack2.isEmpty()) {				
			System.out.print(stack2.pop().value + " ");
		}
	}
}

步骤:

  1. 两个栈
  2. 压头进s1

循环(s1不空){

  1. 弹s1顶的head
  2. 压进s2
  3. 压head的左孩子,然后右孩子进s1 }
  4. 倒空s2

要点:

  • s1 压头,弹一次(进s2),压左,压右
  • 倒s2

后序(一个栈)

代码

public static void postOrderUnRecur2(Node h) {
	if(h != null) {
		 Node c = null;
		 Stack<Node> stack = new Stack<Node>();
		 stack.push(h);
		 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 {
				 h = stack.pop(); //h = c (c = stack.peek();)
				 System.out.print(h.value + " ");
			 }
		 }
	}
}

步骤

h 最新弹出的节点 c 栈顶节点

  1. 初始化:h是head,c空
  2. 压h进栈
    循环(栈不空){
  3. 查看c(栈顶)
    【if】c左不空+ h不是c左+h不是c右
    (说明c有左,且c的子节点没有遍历过「不然h就会是c左右中的一个,是左右中顺序打印的」)
    { 压c左 }
    【else if】c右不空+ h不是右
    (h可以是左孩子,但是c右没有遍历过,因为顺序是左右中)
    {压c右 }
    【else】
    (左右都打印了)
    {弹c打印
    h=c}

要点

  • h 最新弹出的节点
  • c 栈顶节点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值