欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

《剑指offer》面试题6 重建二叉树

程序员文章站 2022-07-17 07:49:45
《剑指offer》答案、分析与笔记Java版 《剑指offer》面试题6:重建二叉树(由一个二叉树的前序和中序序列重建一颗二叉树) 书中方法:我们要重建一棵二叉树,就要不断地找到根节点和根节点的左子结点和右子节点。注意 前序序列 , 它的第一个元素就是二叉树的根节点,后面的元素分为它的左子树的前序遍 ......

《剑指offer》答案、分析与笔记java版
《剑指offer》面试题6:重建二叉树(由一个二叉树的前序和中序序列重建一颗二叉树)

书中方法:我们要重建一棵二叉树,就要不断地找到根节点和根节点的左子结点和右子节点。注意前序序列, 它的第一个元素就是二叉树的根节点,后面的元素分为它的左子树的前序遍历和右子树的前序遍历。现在的问题是如果光靠前序序列,我们只能找到根节点,但是我们不知道两个子序列的长度,也就无法继续用同样的方法找到子树的根节点。这时候我们就需要一个辅助序列——中序序列,根据它的特性,根节点一定在左子序列和右子序列的中间,这样我们就可以确定两个子序列的长度了。

    public treenode build(int[] a, int[] b){
        if(a.length == 0){
            return null;
        }
        return build(a, 0, a.length-1, b, 0, b.length-1);
    }
    
    private treenode build(int[] a, int astart, int aend, int[] b, int bstart, int bend){
        if(astart > aend)return null;
        //构建根节点
        treenode root = new treenode(a[astart]);
        //找到根节点在中序序列中的位置
        int partition = bstart;
        for(int i=bstart; i<=bend; i++){
            if(b[i] == a[astart]){
                partition = i;
                break;
            }
        }
        //在左子序列中继续构建根节点
        root.left = build(a, astart+1, astart+1+partition-1-bstart,
                b, bstart, partition-1);
        //在右子序列中继续构建根节点
        root.right = build(a, astart+partition-bstart+1, aend,
                b, partition+1, bend);
        //返回构建好的根节点
        return root;
        
    }

注:只能用前序+中序或者后序+中序重建二叉树,用前序+后序重建的二叉树不唯一,因为我们不能确定前序序列第一个元素的后面以及后序序列最后一个元素的前面表示的到底是左子树还是右子树。例如一个只有左子树的二叉树3<-2<-1和一个只有右子树的二叉树1->2->3,他们的前序和中序序列是一样的。