剑指Offer面试题:5.重建二叉树

一题目:重建二叉树二思路先根据前序遍历序列的第一个数字创建根结点,接下来在中序遍历序列中找到根结点的位置,这样就能确定左、右子树结点的数量。在前序遍历和中序遍历的序列中划分了左、右子树结点的值

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

全栈程序员社区此处内容已经被作者隐藏,请输入验证码查看内容
验证码:
请关注本站微信公众号,回复“验证码”,获取验证码。在微信里搜索“全栈程序员社区”或者“www_javaforall_cn”或者微信扫描右侧二维码都可以关注本站微信公众号。

一 题目:重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示的二叉树并输出它的头结点。

         
剑指Offer面试题:5.重建二叉树

二 思路

  先根据前序遍历序列的第一个数字创建根结点,接下来在中序遍历序列中找到根结点的位置,这样就能确定左、右子树结点的数量。在前序遍历和中序遍历的序列中划分了左、右子树结点的值之后,就可以递归地去分别构建它的左右子树。

三 代码实现

(1)索引实现

struct TreeNode
{
    int data;
    TreeNode* pLeft;
    TreeNode* pRight;
};

// 重构二叉树
TreeNode* RebulidTree(int *pre, int *mid, int len)
{
    if(NULL == pre || NULL == mid || len < 0)
    {
        return NULL;
    }
    // 根据前序遍历得到根节点
    int root = pre[0];
    TreeNode *pNode = new TreeNode;
    pNode->data = root;
    pNode->pLeft = pNode->pRight = NULL;
    
    int i = 0;
    // 根据根节点将中序遍历结果分成左子树和右子树,前提肯定能找到
    for (; i < len;i ++)
    {
        if (root == mid[i])
        {
            break;
        }
    }
    if (i > 0)
    {
        int *midleft = new int[i];
        memcpy(midleft, mid, sizeof(int) * i);
        int *preleft = new int[i];
        memcpy(preleft, &pre[1], sizeof(int)*i);
        pNode->pLeft = RebulidTree(preleft, midleft, i);
        delete[] midleft;
        delete[] preleft;
    }
    if (i < len-1)
    {
        int *midright = new int[len - i - 1];
        // 将中序分配左子树,右子树
        memcpy(midright, &mid[i+1], sizeof(int)*(len-i-1));
        // 将前序分配左子树和右子树
        int *preright = new int[len-i-1];
        memcpy(preright, &pre[i + 1], sizeof(int)*(len-i-1));
        pNode->pRight = RebulidTree(preright, midright, len - i - 1);
        delete[] midright;
        delete[] preright;
    }
    
    return pNode;
}

(2)指针实现

struct TreeNode
{
    int data;
    TreeNode* pLeft;
    TreeNode* pRight;
};

TreeNode* StructNode(int *StartPre, int *EndPre, int *StartMid, int *EndMid)
{
    // 根据前序遍历得到根节点
    int nRootValue = StartPre[0];
    TreeNode *pNode = new TreeNode;
    pNode->data = nRootValue;
    pNode->pLeft = pNode->pRight = NULL;

    if (StartPre == EndPre)
    {
        if ((StartMid == EndMid) && (*StartPre == *StartMid))
        {
            return pNode;
        }
        else
        {
            throw std::exception("Invalid input");
        }
    }
    // 在中序遍历中找到根结点的值
    int *RootMid = StartMid;
    while(RootMid < EndMid && *RootMid != nRootValue)
    {
        RootMid ++;
    }
    // 若没找到,抛出异常
    if(RootMid == EndMid && *RootMid != nRootValue)
    {
        throw std::exception("Invalid input");
    }

    int nLeftLength = RootMid - StartMid;
    int *LeftPreEnd = StartPre+nLeftLength;
    if (nLeftLength > 0)
    {
        pNode->pLeft = StructNode(++StartPre, LeftPreEnd, StartMid, RootMid-1);
    }
    if (nLeftLength < EndMid - StartMid)
    {
        pNode->pRight = StructNode(LeftPreEnd+1, EndPre,  RootMid+1, EndMid);
    }
    return pNode;
}

TreeNode* RebulidTree_2 (int *pre, int *mid, int len)
{
    if(NULL == pre || NULL == mid || len < 0)
    {
        return NULL;
    }

    return StructNode(pre, pre + len -1, mid, mid+len-1);
}

void main()
{
    int pre[] = {1,2,4,7,3,5,6,8};
    int mid[] = {4,7,2,1,5,3,8,6};

    TreeNode* p =RebulidTree_2(pre, mid, 8);
    return;
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120170.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • UDP攻击是什么呢

    UDP攻击是什么呢用户数据报协议(UDP)是一个无连接协议。当数据包经由UDP协议发送时,发送双方无需通过三次握手建立连接,接收方必须接收处理该资料包。因此大量的发往受害主机UDP报文能使网络饱和。在一起UDP洪流攻击中,UDP报文发往受害系统的随机或指定端口。通常,UDP洪流攻击设定成指向目标的随机端口。这使得受害系统必须对流入数据进行分析以确定哪个应用服务请求了数据。如果受害系统在某个被攻击埠没有运行服务,它将用ICMP报文响应一个“目标端口不可达”消息。通常,攻击中的DDOS工具会伪造攻击包的源IP地址。这有助于隐藏

    2022年10月2日
    0
  • js编写HTML通过document.cookie写入不了cookie的问题[通俗易懂]

    js编写HTML通过document.cookie写入不了cookie的问题[通俗易懂]js中通过document.cookie写入不了cookie的问题使用VScode编写HTML应用cookie进行存储,发现编写无法读取到cookie的内容,即未能实现cookie存储。作为新手问题,可以考虑这个原因:只有当用在服务器或者本地的服务器中的时候,才能使用这个方法写入cookie,所以VScode没有使用服务器方式?这个原因可以通过方案一尝试解决:打开VScode,点击左侧扩展,输入liveserver,点击安装即可;安装成功后再VS界面右下角可以看到相应提示

    2022年7月16日
    62
  • ip addr add配置ip_ip helper-address

    ip addr add配置ip_ip helper-addressbroadcastADDRESS—-协议广播地址,可以简写成brd,此外可以简单的在后面加上”+”表示广播地址由协议地址加主机位全置1组成,”-“则表示主机位全置0。例如你的配置:ipaddradd127.0.0.1/8devlobrd+则表示广播地址为127.255.255.255,网络地址(前8位)为127,主机地址(后面的24位)全为1,加起来为广播地址。扩展:ipad…

    2022年7月27日
    281
  • vue 深入响应式原理 注意事项

    vue 深入响应式原理 注意事项对vue.js的响应式的原理的理解,有助于更加灵活的使用vue,和避开一些坑所以了解其运行原理十分重要

    2022年5月9日
    40
  • Alex 的 Hadoop 菜鸟教程: 第10课 Hive 安装和使用教程

    Alex 的 Hadoop 菜鸟教程: 第10课 Hive 安装和使用教程Hive提供了一个让大家可以使用sql去查询数据的途径。让大家可以在hadoop上写sql语句。但是最好不要拿Hive进行实时的查询。因为Hive的实现原理是把sql语句转化为多个MapReduce任务所以Hive非常慢,官方文档说Hive适用于高延时性的场景而且很费资源。

    2022年6月7日
    94
  • ZOJ 3826 Hierarchical Notation 模拟

    ZOJ 3826 Hierarchical Notation 模拟

    2022年1月2日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号