从后序遍历和中序遍历中还原二叉树(搭配前中后层序遍历输出还原的二叉树)

核心思路

*从后序遍历和中序遍历中还原二叉树:*与从前序和中序遍历中还原二叉树一致,因为后序遍历区间的末尾元素就是中序遍历的根节点,因此,用后序遍历区间末尾元素初始化根节点,用中序遍历根节点左区间和后序遍历左子树区间构造二叉树的左子树,用中序遍历根节点右区间和后序遍历右子树区间构造二叉树的右子树,最后返回根节点。返回条件是当中序遍历区间的左端点大于右端点,说明没有元素来构造二叉树,就返回null。
*层序遍历思路:*用二叉树根节点初始化队列,while循环内,当队列不为空,就将队列中的节点取出,来初始化一个根节点,然后打印该节点值。然后依次将左子树的根节点加入队列,右子树的根节点加入队列。
*前中后序遍历思路:*dfs参数是根节点,不同之处是,
前序遍历是先打印根节点元素,再递归调用左子树和右子树。
中序遍历是先递归调用左子树,再打印根节点元素,最后递归调用右子树。
中序遍历是先递归调用左子树,再递归调用右子树,最后打印根节点元素。

算法设计流程

用后序遍历区间末尾元素初始化根节点,用中序遍历根节点左区间和后序遍历左子树区间构造二叉树的左子树,用中序遍历根节点右区间和后序遍历右子树区间构造二叉树的右子树,最后返回根节点。返回条件是当中序遍历区间的左端点大于右端点,说明没有元素来构造二叉树,就返回null。

代码细节

import javax.swing.tree.TreeNode;
import java.util.*;

public class Main {

    public static class TreeNode{
        int val;
        TreeNode left;
        TreeNode right;

        public TreeNode() {
        }

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

    //由后续和中序遍历构造二叉树
    private static TreeNode dfs(int[] inorder, int i_l, int i_r, int[] postorder, int p_l, int p_r) {
        if (i_l>i_r)return null;
        TreeNode root=new TreeNode(postorder[p_r]);
        for (int i = i_l; i <=i_r; i++) {
            if (inorder[i]== root.val){
                int rootIndex=i;
                root.left=dfs(inorder,i_l,rootIndex-1,postorder,p_l,rootIndex-1-i_l+p_l);
                root.right=dfs(inorder,rootIndex+1,i_r,postorder,rootIndex-i_l+p_l,p_r-1);
                break;
            }
        }
        return root;
    }

//    //由后续和中序遍历构造二叉树
//    private static TreeNode dfs(char[] inorder, int i_l, int i_r, char[] postorder, int p_l, int p_r) {
//        if (i_l>i_r)return null;
//        TreeNode root=new TreeNode(postorder[p_r]);
//        for (int i = i_l; i <=i_r; i++) {//注意这里是小于等于号
//            if (inorder[i]== (char) root.val){
//                int rootIndex=i;
//                root.left=dfs(inorder,i_l,rootIndex-1,postorder,p_l,rootIndex-1-i_l+p_l);
//                root.right=dfs(inorder,rootIndex+1,i_r,postorder,rootIndex-i_l+p_l,p_r-1);
//                break;
//            }
//        }
//        return root;
//    }
前序遍历
//    public static void preorder(TreeNode root, List<Integer> ans){
//        if (root==null)return;
//        ans.add(root.val);
//        preorder(root.left,ans);
//        preorder(root.right,ans);
//    }
    //中序遍历
    public static void inorder(TreeNode root, List<Integer> ans){
        if (root==null)return;
        inorder(root.left,ans);
        ans.add(root.val);
        inorder(root.right,ans);
    }
//    //后序遍历
//    public static void postorder(TreeNode root, List<Integer> ans){
//        if (root==null)return;
//        postorder(root.left,ans);
//        postorder(root.right,ans);
//        ans.add(root.val);
//    }
    //层序遍历
    public static void bfs(TreeNode root){
        if (root==null)return;
        Queue<TreeNode> queue=new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()){
            TreeNode node=queue.poll();
            System.out.print(node.val);
            if (node.left!=null){
                queue.add(node.left);
            }
            if (node.right!=null){
                queue.add(node.right);
            }
        }
    }


    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        String[] strin=scanner.nextLine().split(" ");
        String[] strpo=scanner.nextLine().split(" ");
        int[] inorder=new int[strin.length];
        int[] postorder=new int[strpo.length];
        for (int i = 0; i < inorder.length; i++) {
            inorder[i]=Integer.parseInt(strin[i]);
        }
        for (int i = 0; i < postorder.length; i++) {
            postorder[i]=Integer.parseInt(strpo[i]);
        }
//        String str= scanner.nextLine();
//        String[] strNum=str.split(" ");
//        char[] postorder=strNum[0].toCharArray();
//        char[] inorder=strNum[1].toCharArray();

        TreeNode root=dfs(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
        List<Integer> ans=new ArrayList<>();
//        preorder(root,ans);
//        inorder(root,ans);
//        postorder(root,ans);
//        System.out.println(ans);

        bfs(root);

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值