根据一棵树的前序遍历与中序遍历构造二叉树。(中序和后序呢)

本文详细解析了如何利用先序遍历与中序遍历、中序遍历与后序遍历来构建二叉树的方法。通过递归算法,确定根节点,并划分左右子树,最终实现树的完整构建。

已知一颗树的先序和中序遍历结果,我们是可以构造唯一的一颗二叉树

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private int index = 0;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        index = 0;
        //递归过程中,需要处理到某个具体的子树
        //递归先序
        return buildTreeHelper(preorder,inorder,0,inorder.length);
    }
    private TreeNode buildTreeHelper(int[] preorder,int[] inorder,int inorderleft, int inorderright){
        if(inorderleft >= inorderright){
            //空子树
            return null;
        }
        if(index >= preorder.length){
            return null;
        }
        //取出当前值构造当前子树根节点
        TreeNode root = new TreeNode(preorder[index]);
        index++;//取完这个节点就可以取下一个节点了
        //要找到这个节点在中序遍历中的位置
        int pos = find(inorder,inorderleft,inorderright,root.val);
        root.left = buildTreeHelper(preorder, inorder,inorderleft ,pos );
        root.right = buildTreeHelper(preorder,inorder,pos+1,inorderright);
        return root;
    }
    private int find(int[] inorder,int inorderleft,int inorderright,int val){
        for(int i = inorderleft;i < inorderright ; i++){
            if(inorder[i] == val){
                return i;
            }
        }
        return -1;
    }
}

若知道中序和后序

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private int index = 0;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        index = postorder.length - 1;
        return buildTreehelper2(postorder,inorder,0,inorder.length);
    }
    private TreeNode buildTreehelper2(int[] postorder,int[] inorder,int inorderleft,int inorderright){
        if(inorderleft >= inorderright){
            return null;
        }
        if(index < 0){
            return null;
        }
        TreeNode root = new TreeNode(postorder[index]);
        index--;
        int pos = find(inorder,inorderleft,inorderright,root.val);
        root.right = buildTreehelper2(postorder,inorder,pos+1,inorderright);
        root.left = buildTreehelper2(postorder,inorder,inorderleft,pos);
        return root;
    }
    private int find(int[] inorder,int inorderleft,int inorderright,int val) {
        for (int i = inorderleft; i < inorderright; i++) {
            if (inorder[i] == val) {
                return i;
            }
        }
        return -1;
    }
}

其实这两种构建方法都是类似

依次遍历先序(或后序)的数组,

先序和中序
先序的话第一个值作为根节点,在中序找到这个值的下标,左边是左子树,右边是右子树,再递归建立左子树(此时先序就会往后遍历),递归建立右子树(心中永远有个三节点小树)

中序和后序

先序的话第一个值作为根节点,在中序找到这个值的下标,右边是右子树,左边是左子树,再递归建立右子树(此时后序就会往前遍历),递归建立左子树(心中永远有个三节点小树)


https://www.nowcoder.com/questionTerminal/5ae5174f17674e458028ce12bc8bfe0b



import java.util.Scanner;

public class Main {
    private static int index = 0;
    public static void main(String[] args) {
        index = 0;
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] prevorder = new int[size];
        int[] inorder = new int[size];
        for (int i = 0; i < size; i++) {
            prevorder[i] = scanner.nextInt();
        }
        for (int i = 0; i < size; i++) {
            inorder[i] = scanner.nextInt();
        }
        helper(prevorder,inorder,0,inorder.length);
    }
    public static void helper(int[] prevorder,int[] inorder ,int inorderLeft,int inorderRight){
        if (inorderLeft >= inorderRight){
            return;
        }
        if (index >= prevorder.length){
            return;
        }
        int val = prevorder[index];
        int pos = find(inorder,inorderLeft,inorderRight,prevorder[index]);
        index++;

        helper(prevorder,inorder,inorderLeft,pos);
        helper(prevorder,inorder,pos + 1,inorderRight);
        System.out.print(val);
        System.out.print(" ");
    }
    public static int find(int[] inorder,int left,int right,int val){
        for (int i = left ; i <right ; i++) {
            if (val == inorder[i]){
                return i;
            }
        }
        return -1;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值