二叉树创建
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);
}
}
}
步骤:
- 压头 head 循环 (直到stack空):
- 弹栈顶+打印 cur
- 压右孩子 -左孩子
要点:
- 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;
}
}
}
}
步骤:
循环(只要栈不空 或 头不空):
(如果头不空
- 压头
- 头=头的左孩子
(否则头空
- 弹栈顶+打印
- 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 + " ");
}
}
}
步骤:
- 两个栈
- 压头进s1
循环(s1不空){
- 弹s1顶的head
- 压进s2
- 压head的左孩子,然后右孩子进s1 }
- 倒空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 栈顶节点
- 初始化:h是head,c空
- 压h进栈
循环(栈不空){- 查看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 栈顶节点