SDUTOJ1291数据结构上机测试4.1:二叉树的遍历与应用1

版权声明:iQXQZX https://blog.csdn.net/Cherishlife_/article/details/84963184

以SDUTOJ1291数据结构上机测试4.1:二叉树的遍历与应用1为例

https://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2711/pid/1291

思路:

递归实现,化解子问题解决。

先序:ABDCEF

中序:BDAECF

第一步:根据先序遍历的特点,我们可以简单地知道根节点为A

第二步:观察中序,其中root节点A左侧的BD必然是root的左子树,A右侧的ECF必定是root的右子树

第三步:观察左子树BD,左子树中的根节点必定是大树的leftchild。在先序中大树的leftchild位于root之后,所以左子树的根节点是B。

第四步:同理,root的右子树的节点ECF中的根节点也可以通过前序遍历得到。root的右子树节点ECF中的根节点也可以通过前序遍历求得。在前序遍历中,一定是先把root和root的所有左子树节点遍历完之后才会遍历右子树,并且遍历的左子树的第一个节点就是左子树的根节点。同理,遍历的右子树的第一个节点就是右子树的根节点。

第五步,观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。最后就可以还原一棵树了。该步递归的过程可以简洁表达如下:

1 确定根,确定左子树,确定右子树。

扫描二维码关注公众号,回复: 4491098 查看本文章

2 在左子树中递归。

3 在右子树中递归。

4 打印当前根。

代码实现

#include <bits/stdc++.h>
using namespace std;
void make(int len, char *s1, char *s2, char *s) // s1为先序 s2为中序
{
    int i;
    if (len <= 0)
        return; // return 必不可少 否则死循环
    else
    {
        for (i = 0; i < len; i++)
        {
            if (s1[0] == s2[i]) // 在中序中搜索根节点 实现递归
                break;
        }
    }
    // 关键部分
    make(i, s1 + 1, s2, s);                           // 搜索上次搜索左侧部分
    make(len - i - 1, s1 + i + 1, s2 + i + 1, s + i); // 搜索上次搜索右侧部分
    s[len - 1] = s1[0];                               // 后序输出 把递归找出的根节点从后存入 也就是打印当前根
}
int main()
{
    char s1[100], s2[100], s[100];
    scanf("%s %s", s1, s2);
    int len = strlen(s1);
    // s[len] = '\0'; // 不要忘记封口
    make(len, s1, s2, s);
    s[len] = '\0'; // 不要忘记封口
    cout << s << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Cherishlife_/article/details/84963184
今日推荐