public class PreInPosTraversal {
public static class Node {
public int number;
public String name;
public Node left;
public Node right;
public Node(int number, String name) {
this.number = number;
this.name = name;
}
@Override
public String toString() {
return "Node{" +
"number=" + number +
", name='" + name + '\'' +
'}';
}
}
/**
* 递归前序遍历
* @param head
*/
public static void preOrderRecur(Node head, List<String> res) {
if (head == null) {
return;
}
res.add(head.name);
preOrderRecur(head.left, res);
preOrderRecur(head.right, res);
}
/**
* 递归中序遍历
* @param head
*/
public static void inOrderRecur(Node head, List<String> res) {
if (head == null) {
return;
}
inOrderRecur(head.left, res);
res.add(head.name);
inOrderRecur(head.right, res);
}
/**
* 递归后续遍历
* @param head
*/
public static void posOrderRecur(Node head, List<String> res) {
if (head == null) {
return;
}
posOrderRecur(head.left, res);
posOrderRecur(head.right, res);
res.add(head.name);
}
/**
* 非递归前序遍历:中 左 右
* 压头节点,然后先压右再压左(没有就不压)
* 因为每一次要弹出一个所以要先压右,再压左,左先出,右后出
* @param head
*/
public static List<String> preOrderUnRecur(Node head) {
ArrayList<String> res = new ArrayList<>();
if (head != null) {
Stack<Node> stack = new Stack<>();
//首先将父节点入栈
stack.add(head);
//当栈不为空的时候
while (!stack.isEmpty()) {
//最先弹出的是父节点
Node curNode = stack.pop();
res.add(curNode.name);
//中序遍历,左在右的前面,右子节点先入栈
if (curNode.right != null) {
stack.push(curNode.right);
}
//中序遍历,左在右的前面,左子节点后入栈
if (curNode.left != null) {
stack.push(curNode.left);
}
}
}
return res;
}
/**
* 非递归中序遍历:左 中 右
* 如果当前节点为空,从栈中弹出一个打印,当前节点往右
* 如果当前节点不为空,当前节点入栈,然后往左
* @param head
*/
public static List<String> inOrderUnRecur(Node head) {
ArrayList<String> res = new ArrayList<>();
if (head != null) {
Node curNode = head;
Stack<Node> stack = new Stack<>();
while (!stack.isEmpty() || curNode != null) {
//当前节点不为空,往左串
if (curNode != null) {
stack.push(curNode);
curNode = curNode.left;
} else {
//当前节点为空,从栈中拿出一个,打印,往右串
curNode = stack.pop();
res.add(curNode.name);
curNode = curNode.right;
}
}
}
return res;
}
/**
* 前序是: 中 左 右 ——> 改为: 中 右 左 即先压左,再压右
* 这时候上面的出栈顺序就是 中 右 左,出栈后再入另一个栈
* 然后再出栈就是:左 右 中 的顺序,即后续
* @param head
*/
public static List<String> posOrderUnRecur1(Node head) {
ArrayList<String> res = new ArrayList<>();
if (head != null) {
Stack<Node> s1 = new Stack<>();
Stack<Node> s2 = new Stack<>();
s1.push(head);
while (!s1.isEmpty()) {
// 出栈
Node curNode = s1.pop();
//这个时机就是前序遍历的打印,我们在这里放入栈中
//System.out.print(curNode.name + " ");
// 放入到另一个栈中
s2.push(curNode);
// 先向左再向右,出栈就是 中 右 左
if (curNode.left != null) {
s1.push(curNode.left);
}
if (curNode.right != null) {
s1.push(curNode.right);
}
}
while (!s2.isEmpty()) {
// 此时从s2出栈就是 左 右 中
res.add(s2.pop().name);
}
}
return res;
}
//炫技
public static List<String> posOrderUnRecur2(Node head) {
ArrayList<String> res = new ArrayList<>();
if (head != null) {
Stack<Node> stack = new Stack<>();
stack.push(head);
Node curNode;
while (!stack.isEmpty()) {
curNode = stack.peek();
if (curNode.left != null && head != curNode.left && head != curNode.right) {
stack.push(curNode.left);
} else if (curNode.right != null && head != curNode.right) {
stack.push(curNode.right);
} else {
res.add(stack.pop().name);
head = curNode;
}
}
}
return res;
}
public static void main(String[] args) {
Node head = new Node(1, "中国");
Node node1 = new Node(2, "广东");
Node node2 = new Node(3, "四川");
Node node3 = new Node(4, "广州");
Node node4 = new Node(5, "佛山");
Node node5 = new Node(6, "成都");
Node node6 = new Node(7, "绵阳");
ArrayList<String> res1 = new ArrayList<>();
ArrayList<String> res2 = new ArrayList<>();
ArrayList<String> res3 = new ArrayList<>();
head.left = node1;
head.right = node2;
node1.left = node3;
node1.right = node4;
node2.left = node5;
node2.right = node6;
// 递归
System.out.print("递归前序遍历:");
preOrderRecur(head, res1);
System.out.println(res1);
System.out.print("递归中序遍历:");
inOrderRecur(head,res2);
System.out.println(res2);
System.out.print("递归后序遍历:");
posOrderRecur(head,res3);
System.out.println(res3);
// 递归前序遍历:[中国, 广东, 广州, 佛山, 四川, 成都, 绵阳]
// 递归中序遍历:[广州, 广东, 佛山, 中国, 成都, 四川, 绵阳]
// 递归后序遍历:[广州, 佛山, 广东, 成都, 绵阳, 四川, 中国]
// 非递归
List<String> res4 = preOrderUnRecur(head);
System.out.println("非递归前序遍历:"+res4);
List<String> res5 = inOrderUnRecur(head);
System.out.println("非递归中序遍历:"+res5);
List<String> res6 = posOrderUnRecur1(head);
System.out.println("非递归后序遍历:"+res6);
List<String> res7 = posOrderUnRecur2(head);
System.out.println("非递归后序遍历:"+res7);
}
// 非递归前序遍历:[中国, 广东, 广州, 佛山, 四川, 成都, 绵阳]
// 非递归中序遍历:[广州, 广东, 佛山, 中国, 成都, 四川, 绵阳]
// 非递归后序遍历:[广州, 佛山, 广东, 成都, 绵阳, 四川, 中国]
// 非递归后序遍历:[广州, 佛山, 广东, 成都, 绵阳, 四川, 中国]
}
递归遍历:
非递归的中序遍历思路: