输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

问题描述:

    输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

  思路:

  在二叉树的前序遍历序列中,第一个数字总是树的根结点的值。但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边。因此我们需要扫描中序遍历序列,才能找到根结点的值。

  如下图所示,前序遍历序列的第一个数字1就是根结点的值。扫描中序遍历序列,就能确定根结点的值的位置。根据中序遍历特点,在根结点的值1前面的3个数字都是左子树结点的值,位于1后面的数字都是右子树结点的值。

  

  同样,在前序遍历的序列中,根结点后面的3个数字就是3个左子树结点的值,再后面的所有数字都是右子树结点的值。这样我们就在前序遍历和中序遍历两个序列中,分别找到了左右子树对应的子序列。

  既然我们已经分别找到了左、右子树的前序遍历序列和中序遍历序列,我们可以用同样的方法分别去构建左右子树。也就是说,接下来的事情可以用递归的方法去完成。
  完整的代码示例如下,方式一使用数组存储前序遍历序列和中序遍历序列;方式二使用容器存储。

#include<iostream>
using namespace std;  

template<class T>
struct BinaryTreeNode
{
    T _value; //数据
    BinaryTreeNode<T>* _left; //左孩子
    BinaryTreeNode<T>* _right; //右孩子  

    BinaryTreeNode()
        : _value()
        , _left(NULL)
        , _right(NULL)
    {}  

};
template<class T>
class BinaryTree
{
public:
    BinaryTreeNode<T>* ConstructCore(int* startPre,int* endPre,int* startIn,int* endIn)
    {
        int rootValue = startPre[0];  //前序遍历的第一个数字就是根节点的值
        BinaryTreeNode<T>* root = new BinaryTreeNode<T>();
        root->_value = rootValue;
        root->_left = root->_right = NULL;
        cout << root->_value<< " ";  

        if (startPre == endPre)
        {
            if (startIn == endIn && *startPre == *startIn)
            {
                return root;
            }
            else
            {
                return NULL;
            }
        }  

        int* rootIn = startIn;
        //在中序遍历中找根节点的值
        while (*rootIn != rootValue && rootIn <= endIn)
        {
            ++rootIn;
        }
        if (rootIn == endIn && *rootIn != rootValue)
            return NULL;  

        int leftLength = rootIn - startIn;//左子树长度   中序遍历序列中根节点前面的数字都是左子树节点的值
        int* leftEnd = startPre + leftLength;//前序遍历序列中左子树的值
        //构建左子树
        if (leftLength > 0)
        {
            root->_left=ConstructCore(startPre+1,leftEnd,startIn,rootIn-1);
        }
        //构建右子树
        if (leftLength < endPre - startPre)
        {
            root->_right = ConstructCore(leftEnd+1,endPre,rootIn+1,endIn);
        }
        return root;
    }
    BinaryTreeNode<T>* Construct(int* preorder, int* inorder, int length)
    {
        if (preorder == NULL || inorder == NULL || length <= 0)
            return NULL;
        return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1);
    }
};  

int main()
{
    int preorder[] = { 1,2,4,7,3,5,6,8 };
    int inorder[] = { 4,7,2,1,5,3,8,6 };
    BinaryTree<int> bt;
    BinaryTreeNode<int>* root=bt.Construct(preorder, inorder, 8);
    return 0;
}

  

时间: 2024-11-03 21:28:56

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。的相关文章

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树

问题描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边.因此我们需要扫描中序遍历序列,才能找到根结点的值. 如下图所示,

输入某二叉树的前序遍历和中序遍历的结果,重建出该二叉树

//================================================================== // <剑指Offer--名企面试官精讲典型编程题>代码 // 作者:何海涛 //================================================================== // 面试题7:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输 // 入的前序遍历和中序遍历的结果中都

N4-某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. //本题思路参考另一个大神写的代码 其原地址为:https://www.nowcoder.com/profile/566744/codeBookDetail?submissionId=1516321 /** * 输入某二叉树的前序遍历和中序遍历的结果,

查找数组中重复的数字

题目来源于<剑指Offer>中的面试题3:找出数组中重复的数字. // 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, // 也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如,如果输入长度为7的数组{2, 3, 1, 0, 2, 5, 3}, // 那么对应的输出是重复的数字2或者3. 解决方法有多种,包括数组排序,哈希表法,以及作者推荐的重排数组法.此处介绍自己的一个做法,以空间换时间,通过新建数组来实现快速查

1-找出数组中重复的数字

力扣-面试题03. 数组中重复的数字 修改数组 不修改数组 题目描述: 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字. 输入: [2,3,1,0,2,5,3] 输出: 2or3 //把每个数放到对应的位置=>i=nums[i] class Solution { public: int duplicateInArray(vector<int>&

一起来刷《剑指Offer》——不修改数组找出重复的数字(思路及Python实现)

数组中重复的数字 在上一篇博客中<剑指Offer>-- 题目一:找出数组中重复的数字(Python多种方法实现)中,其实能发现这类题目的关键就是一边遍历数组一边查满足条件的元素. 然后我们在博客用最复杂的方式学会数组(Python实现动态数组)这篇博客中介绍了数组这一结构的本质,并自己动手实现了一个动态数组. 今天我们介绍一下另一道来自<剑指Offer>的关于数组的面试题--不修改数组找出重复的数字. 不修改数组找出重复的数字 题目二:不修改数组找出重复的数字 给定一个长度为 n+

不修改数组找出重复的数字(c语言)

让人瑟瑟发抖的面试题... 来我们看一下题目在一个 长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的.请找出数组中任意一个重复的数字,但不能修改输入的数组.注意:时间复杂度O(n),空间复杂度O(1) 找出数组中重复的数字(c语言)怎么解决勒???分析:利用题目中元素处于1~n的范围,把元素分为两组,判断两组元素个数,如果大于范围,则重复的数字就在这个范围内.例如:1~3范围中有4个数,说明其中至少有一个重复的数字.按此二分下去,将会剩下一个数字有两个,最后输出

用MFC完成一个简单的猜数字游戏: 输入的四位数中,位置和数字都正确为A,数字相同而位置不同的为B。

最近学习了MFC一些比较基础的知识,所以打算通过做一个简单的数字游戏来理解MFC的流程并进一步熟悉其操作. 在这里,我做了一个猜数字的小游戏.第一步当然是设计主界面,先给大家展示一下游戏界面: 主界面: 从这个主界面可以看到,它包含标题,菜单栏,工具栏. 标题是给人一个认识,这是什么游戏,标题设置为:“猜数游戏”: 而菜单栏和工具栏才是游戏的核心,它要保证能够完成游戏的基本功能. 菜单栏和工具栏是对应的,包含了”start“,"help","restart"这三个菜

面试题3:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

package siweifasan_6_5; /** * @Description:在一个长度为n的数组里的所有数字都在0到n-1的范围内. * 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次. * 请找出数组中任意一个重复的数字. * 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2. * @Parameters: // Parameters: // numbers: an array of integers //