package ccnu.offer.tree;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.Stack;
public class Demo02 {
public static void main(String[] args) {
Demo02 d = new Demo02();
Node root1 = d.createBiTreeByPreIn(new int[]{1, 2, 4, 6, 7, 3, 5, 8, 9}, new int[]{2, 6, 4, 7, 1, 5, 9, 8, 3}, 0, 0, 9);
System.out.println(d.preOrder1(root1));
System.out.println(d.inOrder1(root1));
System.out.println(d.postOrder1(root1));
System.out.println(d.levelOrder(root1));
System.out.println(d.levelOrder1(root1));
}
public Node createBiTree(){
Scanner sc = new Scanner(System.in);
int val;
Node root;
val = sc.nextInt();
if(val == -1){
return null;
}else{
root = new Node(val);
root.lchild = createBiTree();
root.rchild = createBiTree();
}
return root;
}
public Node createBiTreeByPreIn(int[] pre, int[] in, int preBegin, int inBegin, int len){
if(pre == null || in == null || pre.length != in.length || pre.length == 0 || in.length == 0){
return null;
}
if(len <= 0){
return null;
}
Node root = new Node(pre[preBegin]);
int rootIndex;
for(rootIndex = 0; in[rootIndex] != pre[preBegin]; rootIndex++);
root.lchild = createBiTreeByPreIn(pre, in, preBegin + 1, inBegin, rootIndex - inBegin);
root.rchild = createBiTreeByPreIn(pre, in, preBegin + (rootIndex - inBegin) + 1, rootIndex + 1, len - (rootIndex - inBegin) - 1);
return root;
}
public void preOrder(Node root){
if(root != null){
System.out.print(root.val);
preOrder(root.lchild);
preOrder(root.rchild);
}
}
public ArrayList<Integer> preOrder1(Node root){
ArrayList<Integer> preSerials = new ArrayList<Integer>();
Stack<Node> s = new Stack<Node>();
while(root != null || !s.isEmpty()){
if(root != null){
preSerials.add(root.val);
s.push(root);
root = root.lchild;
}else{
root = s.pop();
root = root.rchild;
}
}
return preSerials;
}
public void inOrder(Node root){
if(root != null){
inOrder(root.lchild);
System.out.print(root.val);
inOrder(root.rchild);
}
}
public ArrayList<Integer> inOrder1(Node root){
ArrayList<Integer> inSerials = new ArrayList<Integer>();
Stack<Node> s = new Stack<Node>();
while(root != null || !s.isEmpty()){
if(root != null){
s.push(root);
root = root.lchild;
}else{
root = s.pop();
inSerials.add(root.val);
root = root.rchild;
}
}
return inSerials;
}
public void postOrder(Node root){
if(root != null){
postOrder(root.lchild);
postOrder(root.rchild);
System.out.print(root.val);
}
}
public ArrayList<Integer> postOrder1(Node root){
ArrayList<Integer> postSerials = new ArrayList<Integer>();
Stack<Node> s = new Stack<Node>();
Node isAccess = null;
while(root != null || !s.isEmpty()){
if(root != null){
s.push(root);
root = root.lchild;
}else{
root = s.peek();
root = root.rchild;
if(root == null || isAccess == root){
root = s.pop();
postSerials.add(root.val);
isAccess = root;
root = null;
}else{
s.push(root);
root = root.lchild;
}
}
}
return postSerials;
}
public ArrayList<Integer> postOrder2(Node root) {
ArrayList<Integer> postSerials = new ArrayList<Integer>();
ArrayList<Integer> leftPostSerials = new ArrayList<Integer>();
ArrayList<Integer> rightPostSerials = new ArrayList<Integer>();
if (root == null) {
return postSerials;
}
leftPostSerials = postOrder2(root.lchild);
rightPostSerials = postOrder2(root.rchild);
postSerials.addAll(leftPostSerials);
postSerials.addAll(rightPostSerials);
postSerials.add(root.val);
return postSerials;
}
public ArrayList<Integer> levelOrder(Node root){
int levels = 0;
ArrayList<Integer> levelSerials = new ArrayList<Integer>();
LinkedList<Node> levelNodes = new LinkedList<Node>();
Node rightmost1 = null;
Node rightmost2 = null;
while(root != null || !levelNodes.isEmpty()){
if(root != null){
levelNodes.push(root);
rightmost1 = root;
rightmost2 = root;
root = null;
}else{
root = levelNodes.pop();
levelSerials.add(root.val);
if(root.lchild != null){
levelNodes.addLast(root.lchild);
rightmost2 = root.lchild;
}
if(root.rchild != null){
levelNodes.addLast(root.rchild);
rightmost2 = root.rchild;
}
if(root == rightmost1){
levels++;
levelSerials.add(-1);
rightmost1 = rightmost2;
}
root = null;
}
}
System.out.println("levels: " + levels);
return levelSerials;
}
public ArrayList<Integer> levelOrder1(Node root){
ArrayList<Integer> levelSerials = new ArrayList<Integer>();
LinkedList<Node> levelNodes = new LinkedList<Node>();
Stack<Node> accessNodes = new Stack<Node>();
Node rightmost1 = null;
Node rightmost2 = null;
while(root != null || !levelNodes.isEmpty()){
if(root != null){
levelNodes.push(root);
rightmost1 = root;
rightmost2 = root;
root = null;
}else{
root = levelNodes.pop();
accessNodes.push(root);
if(root.lchild != null){
levelNodes.addLast(root.lchild);
rightmost2 = root.lchild;
}
if(root.rchild != null){
levelNodes.addLast(root.rchild);
rightmost2 = root.rchild;
}
if(root == rightmost1){
accessNodes.push(new Node(-1));
rightmost1 = rightmost2;
}
root = null;
}
}
while(!accessNodes.isEmpty()){
levelSerials.add(accessNodes.pop().val);
}
return levelSerials;
}
private class Node{
private int val;
private Node lchild = null;
private Node rchild = null;
public Node(int val) {
this.val = val;
}
}
}