由二叉树序列创建二叉树

kitten 发布于 2024-06-17 263 次阅读


题目:对于含nn>0)个结点的二叉树,所有结点值为int类型,设计一个算法由其先序序列preorder和中序序列inorder创建对应的二叉链存储结构。

这题属于二叉树基础问题

我们假设一个二叉树的先序序列为{1, 2, 4, 5, 3, 6, 7}, 中序序列为{4, 2, 5, 1, 6, 3, 7} 。对于二叉树的序列性质有: 通过先序的第一个元素可知整棵树的根结点。而对于中序遍历来说,根结点在其序列中间位置。所以这个示例中, 根节点值为"1",左子树的先序排列为{2, 4, 5}, 中序排列为{4, 2, 5}, 这样我们就可以得出左子树的两个排列序列, 进而又可以得出左子树根节点为"2"...... 最后, 对于二叉树这种递归数据结构, 我们可以使用简单的递归算法完成题目

class Node {
    int data;
    Node left;
    Node right;
    public Node(int data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

public class CreateBinaryTree {
    public static Node createBinaryTree(int[] preorder, int[] inorder) {
        if (preorder.length == 0 || inorder.length == 0) {
            return null;
        }
        return createBinaryTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
    }
    private static Node createBinaryTree(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) {
        if (preStart > preEnd || inStart > inEnd) {//递归出口
            return null;
        }
        //根节点的值
        int rootVal = preorder[preStart];
        Node root = new Node(rootVal);
        //获取中序序列中根节点的索引值(遍历inStart~inEnd,即中序序列)
        int rootIndex = 0;
        for (int i = inStart; i <= inEnd; i++) {
            if (inorder[i] == rootVal) {
                rootIndex = i;
                break;
            }
        }
        //递归创建左子树,传入左子树的preStart,preEnd,inStart,inEnd
        root.left = createBinaryTree(preorder, preStart + 1, preStart + rootIndex - inStart, inorder, inStart, rootIndex - 1);
        //递归创建右子树
        root.right = createBinaryTree(preorder, preStart + rootIndex - inStart + 1, preEnd, inorder, rootIndex + 1, inEnd);

        return root;
    }

    public static void main(String[] args) {
        int[] preorder = {1, 2, 4, 5, 3, 6, 7};
        int[] inorder = {4, 2, 5, 1, 6, 3, 7};
        Node root = createBinaryTree(preorder, inorder);
        
    }
}