递归法构建二叉树

147 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第42天,点击查看活动详情 >>

递归法构建二叉树

在这之前,我们有曾经学习过了二叉树基于中序遍历数组和后序遍历数组是怎样用递归法遍历的,那么今天我们就来学习另外一种情况——基于前序遍历数组和中序遍历数组如何使用递归法来确定并构建二叉树。

话不多说,我们马上出发。

题目分析

对于给定的两个数组,分别是对同一个二叉树前序遍历、中序遍历的结果,我们需要根据它们来完成二叉树的构建。

算法分析

因为是二叉树,二叉树是一种高度相似的数据结构,也就是说一棵二叉树其实是可以看成由很多棵二叉树组成的。所以咱们这次对二叉树的构建(使用递归法)也是基于这种思想的;这样子,我们就可以先构建一个个子树,最后完成了整个大的二叉树的构建。

当然啦,现在题目给我们的只有二叉树前序遍历的数组和中序遍历的数组,都是数组,而不是子树;虽然这样,但是整体的实现思路还是一致的,我们在递归的时候,递归的不是某个树的根节点或者某个结点,我们递归的入参是二叉树的前序遍历数组、中序遍历数组(当然啦,这里是指二叉树中的子树的遍历结果-)。

经过了算法分析,下面我们就一起来看看具体代码的实现是如何进行的

算法代码的具体实现

首先定义了一个成员变量map来记录中序遍历数组的有关信息:

Map<Integer, Integer> map = new LinkedHashMap<>();

递归调用函数:

public TreeNode buildTree(int[] preorder, int[] inorder) {
            int plen = preorder.length;
            int ilen = inorder.length;
            for (int i = 0; i < ilen; i++) {
                map.put(inorder[i], i);
            }
            return build(preorder, 0, plen - 1, inorder, 0, ilen - 1);
        }

具体的递归函数如下(算法核心内容)

        public TreeNode build (int[] preorder, int pstart, int pend, int[] inorder, int istart, int iend) {
            if (pstart > pend || istart >iend) {
                return null;
            }
            TreeNode root = new TreeNode(preorder[pstart]);
            Integer i = map.get(preorder[pstart]);
​
            // 中序遍历数组中划分出来的右边部分
            int right = iend - i;
​
            int left = i - istart;root.left = build(preorder, pstart + 1, pend + left, inorder, istart, i - 1);
            root.right = build(preorder, pstart + left + 1, pend, inorder, i + 1, iend);
            return root;
        }

总结:

这次我们学习了如何通过递归法来解决基于前序遍历数组、中序遍历数组构建二叉树的问题:

要解决这道题的核心点是需要掌握二叉树前序遍历和中序遍历的具体实现,还要明白他们之前的关系,这样子,在这道综合题面前才可以更好地上手设计算法解决问题。

\