Tree Traversals Again - Java实现

14 篇文章 0 订阅

An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.

在这里插入图片描述
Figure 1

Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: “Push X” where X is the index of the node being pushed onto the stack; or “Pop” meaning to pop one node from the stack.

Output Specification:
For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:
6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

Sample Output:
3 4 2 6 5 1

思路:

根据push的顺序得到先序遍历的序列,再根据pop的顺序得到中序遍历的序列,从而确定唯一的一棵树;然后再得出其后续遍历的序列;

代码如下:
import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.FileReader;

/**
 * 先序,中序固定一颗树
 * 获得后续遍历
 */
public class Main4 {

    private int nodeNum;
    private int flag = 0;

    public static void main(String[] args){
        Main4 self = new Main4();
        BufferedReader br = new BufferedReader(new FileReader(FileDescriptor.in));
        try {
            TreeNode[] tree = self.getTree(br);
            StringBuilder res = new StringBuilder();
            self.getPostOrder(tree, tree[0],res);
            System.out.print(res.substring(0,res.length()-1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //控制台获取输入
    public TreeNode[] getTree(BufferedReader br) throws Exception{
        nodeNum = Integer.parseInt(br.readLine().trim());
        String[] actions = new String[2*nodeNum];
        //中序遍历
        int[] inorder = new int[nodeNum];
        int inFlag = 0;
        //先序遍历
        int[] preorder = new int[nodeNum];
        int pre = 0;
        Stack1 stack = new Stack1(nodeNum);
        //获得动作、先序、中序遍历顺序
        for (int i = 0; i < 2*nodeNum; i++) {
            actions[i] = br.readLine().trim();
            if(actions[i].split(" ").length == 2){
                int temp = Integer.parseInt(actions[i].split(" ")[1]);
                preorder[pre++] = temp;
                stack.push(temp);
            }else{
                inorder[inFlag++] = stack.pop();
            }
        }
        //建立一棵树
        TreeNode[] tree = new TreeNode[nodeNum];
        TreeNode head = getTree(inorder, preorder, tree);
        return tree;

    }

    //给定先序和中序,得出一颗树
    public TreeNode getTree(int[] inorder, int[] preorder,TreeNode[] tree){
        //头结点
        TreeNode head = new TreeNode(preorder[0]);
        tree[flag++] = head;
        if(inorder.length == 1){
            head.setLeft(-1);
            head.setRight(-1);
            return head;
        }
        //左子树先序和中序
        int index = 0;
        for (int i = 0; i < inorder.length; i++) {
            if(inorder[i] == preorder[0]){
                index = i;
                break;
            }
        }
        if (index > 0){
            int[] leftInorder = new int[index];
            //赋值
            for (int i = 0; i < leftInorder.length; i++) {
                leftInorder[i] = inorder[i];
            }
            int[] leftPreorder = new int[index];
            //赋值
            for (int i = 0; i < leftPreorder.length; i++) {
                leftPreorder[i] = preorder[i+1];
            }
            head.setLeft(leftPreorder[0]);
            getTree(leftInorder,leftPreorder,tree);
        }
        if(index < inorder.length-1){
            int[] rightInorder = new int[inorder.length-index-1];
            //赋值
            for (int i = 0; i < rightInorder.length; i++) {
                rightInorder[i] = inorder[index+i+1];
            }
            int[] rightPreorder = new int[inorder.length-index-1];
            //赋值
            for (int i = 0; i < rightPreorder.length; i++) {
                rightPreorder[i] = preorder[index+i+1];
            }
            head.setRight(rightPreorder[0]);
            getTree(rightInorder,rightPreorder,tree);
        }

        return head;
    }

    //后续遍历一棵树
    public void getPostOrder(TreeNode[] tree, TreeNode head,StringBuilder res){

        if (head.getLeft() != -1) {
            TreeNode leftChild = findNodeFromTree(head.getLeft(), tree);
            if(leftChild != null){
                getPostOrder(tree,leftChild,res);
            }
        }
        if(head.getRight() != -1) {
            TreeNode rightChild = findNodeFromTree(head.getRight(), tree);
            if(rightChild != null){
                getPostOrder(tree,rightChild,res);
            }
        }
        res.append(head.getData() + " ");
    }

    //在树中找节点
    public TreeNode findNodeFromTree(int data, TreeNode[] tree){
        for (int i = 0; i < tree.length; i++) {
            if(data == tree[i].getData()){
                return tree[i];
            }
        }
        return null;
    }

}

//树节点
class TreeNode{
    private int data;
    private int left;
    private int right;

    public TreeNode(int data, int left, int right) {
        this.data = data;
        this.left = left;
        this.right = right;
    }

    public TreeNode(int data) {
        this.data = data;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public int getLeft() {
        return left;
    }

    public void setLeft(int left) {
        this.left = left;
    }

    public int getRight() {
        return right;
    }

    public void setRight(int right) {
        this.right = right;
    }
}

//栈
class Stack1{
    private int cap;
    private Integer[] data;
    private int top;

    public Stack1(int cap) {
        this.cap = cap;
        this.top = -1;
        this.data = new Integer[cap];
    }
    //出栈
    public Integer pop(){
        if (this.top == -1){
            return null;
        }else{
            return data[this.top--];
        }
    }
    //入栈
    public boolean push(int num){
        if(this.top == this.cap - 1){
            return false;
        }else {
            data[++this.top] = num;
            return true;
        }
    }
    //获得栈顶元素
    public Integer getTopOne(){
        if (this.top == -1){
            return null;
        }else {
            return data[this.top];
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值