二叉树遍历序列还原·已知中序遍历和后序遍历

二叉树遍历序列还原·已知中序遍历和后序遍历

题目信息

给出二叉树的中序遍历序列和后序遍历序列,编程还原该二叉树。

输入

第1行:二叉树的中序遍历序列
第2行:二叉树的后序遍历序列

输出

二叉树的按层遍历序列

测试样例

测试样例1

badcfeg
bdfgeca
abcdefg

测试样例2

cbdafeg
cbdfgea
adebfgc

测试样例3

edcba
edcba
abcde

解答

#include <iostream>
#include <queue>
#include <stack>
#include <string>

using namespace std;

struct BTreeNode
{
    char data;
    BTreeNode *Left;
    BTreeNode *Right;
};

class BTree
{
public:
    //传参需要注意,二叉树是指针类型的,节点本身就是一个指针:*node。所以需要二级指针才能改变二叉树的内容
    void Create(BTreeNode *Node)
    {//按层创建二叉树
        queue<BTreeNode *> que;
        que.push(Node);
        while (!que.empty())
        {
            char ch;
            ch = getchar();
            BTreeNode *node = que.front();
            que.pop();
            if (ch == '\n')
            {
                break;
            }

            node->data = ch;
            node->Left = new BTreeNode;
            node->Left->data = '\0';
            que.push(node->Left);
            node->Right = new BTreeNode;
            node->Right->data = '\0';
            que.push(node->Right);
        }
    }

    void DisPlay(BTreeNode *Node, int depth)
    {
        if (Node->data != '#' && Node->data != '\0')
        {//既不是空也不是虚节点
            for (int i = 0; i < depth; i++)
            {
                cout << "    ";
            }
            cout << Node->data << endl;
            depth++;
            DisPlay(Node->Left, depth);
            DisPlay(Node->Right, depth);
        }
    }

    void preorderTree(BTreeNode *Node)
    {//前序遍历(根左右)
        if (Node->data != '#' && Node->data != '\0')
        {
            cout << Node->data;
            preorderTree(Node->Left);
            preorderTree(Node->Right);
        }
    }

    void inorderTree(BTreeNode *Node)
    {//中序遍历(左中右)
        if (Node->data != '#' && Node->data != '\0')
        {
            inorderTree(Node->Left);
            cout << Node->data;
            inorderTree(Node->Right);
        }
    }


    void postorderTree(BTreeNode *Node)
    { //后序遍历(左右中)
        if (Node->data != '#' && Node->data != '\0')
        {
            postorderTree(Node->Left);
            postorderTree(Node->Right);
            cout << Node->data;
        }
    }

    void levelTree(BTreeNode *Node)
    {//层序遍历
        queue<BTreeNode *> que;
        if (Node == NULL) return;
        else
        {
            que.push(Node);
            while (!que.empty())
            {
                BTreeNode *node = que.front();
                cout << node->data;
                que.pop();
                if (node->Left->data != '#' && node->Left->data != '\0')
                {
                    que.push(node->Left);
                }
                if (node->Right->data != '#' && node->Right->data != '\0')
                {
                    que.push(node->Right);
                }
            }
        }
    }

    int depthOfTree(BTreeNode *Node)
    {//二叉树深度
        if (Node->data != '#' && Node->data != '\0')
        {
            return max(depthOfTree(Node->Left), depthOfTree(Node->Right)) + 1;
        }
        else
        {
            return 0;
        }
    }

    int getNodeNum(BTreeNode *Node)
    {//返回节点总数目
        if (Node->data != '#' && Node->data != '\0')
        {
            return 1 + getNodeNum(Node->Left) + getNodeNum(Node->Right);
        }
        else
        {
            return 0;
        }
    }

    int getLeafNum(BTreeNode *Node)
    {//返回叶子节点
        if (Node->data == '#' || Node->data == '\0')
        {
            return 0;
        }
        else if ((Node->Left->data == '#' || Node->Left->data == '\0') &&
                 (Node->Right->data == '#' || Node->Right->data == '\0'))
        {
            return 1;
        }
        else
        {
            return getLeafNum(Node->Left) + getLeafNum(Node->Right);
        }
    }

    void SwapTree(BTreeNode *Node)
    {
        if (Node->data != '#' && Node->data != '\0')
        {
            swap(Node->Left, Node->Right);
            SwapTree(Node->Left);
            SwapTree(Node->Right);
        }
        return;
    }

    BTreeNode *restore(string mid, string back, int length)
    {//根据中序和后序两个字符串来建立完整的二叉树
        if (length == 0)
        {
            return NULL;
        }
        BTreeNode *node = new BTreeNode;//先构建一个节点
        node->data = back[length - 1];//使节点值为back中最后一个,因为那个一定是根节点的数值
        int rootIndex;
        for (rootIndex = 0; rootIndex < length; rootIndex++)
        {//找到根节点在中序中的位置
            if (mid[rootIndex] == back[length - 1])
            {
                break;
            }
        }
        node->Left = restore(mid, back, rootIndex);
        if (node->Left == NULL)
        {
            node->Left = new BTreeNode;
            node->Left->data = '#';
        }
        string backmid(mid, rootIndex + 1);
        string backback(back, rootIndex);
        node->Right = restore(backmid, backback, length - rootIndex - 1);
        if (node->Right == NULL)
        {//加入是空指针的话,也为其开上内存,但其值存为#即可
            node->Right = new BTreeNode;
            node->Right->data = '#';
        }
        return node;
    }
};

int main()
{
    //freopen("/Users/zhj/Downloads/test.txt", "r", stdin);
    string mid, back;
    cin >> mid >> back;
    BTreeNode *Root = new BTreeNode;
    BTree bTree;
    Root = bTree.restore(mid, back, back.length());
    bTree.levelTree(Root);
    cout << endl;
    return 0;
}

想法

本题在仍然使用之前的类的基础上做了一个函数的扩充,故需同时满足之前对于空二叉树的判定,其判定条件为data值为#或者是\0.

相关题目

二叉树的建立与基本操作
二叉树最近的公共祖先
二叉树先序,中序,后序,层序遍历还原
二叉树遍历序列还原·已知中序遍历和层序遍历

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhj12399

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值