28. 二叉树遍历

65 阅读1分钟

题目描述

根据给定的二叉树结构描述字符串,输出该二叉树按照中序遍历结果字符串。中序遍历顺序为:左子树,根结点,右子树。

输入描述

由大小写字母、左右大括号、逗号组成的字符串:字母代表一个节点值,左右括号内包含该节点的子节点。

左右子节点使用逗号分隔,逗号前为空则表示左子节点为空,没有逗号则表示右子节点为空。

二叉树节点数最大不超过100。

注:输入字符串格式是正确的,无需考虑格式错误的情况。

输出描述

输出一个字符串为二叉树中序遍历各节点值的拼接结果。

用例

输入 a{b{d,e{g,h{,i}}},c{f}}
输出 dbgehiafc
说明

思路

一定要从内往外拆分,将内层的子树{}变成字符串放在原来的字符串中

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <stack>
using namespace std;

// a{b{d,e{g,h{,i}}},c{f}}

vector<string> split(const string& str, char delimiter)
{
    vector<string> res;
    string tmp;
    stringstream ss(str);
    while (getline(ss, tmp, delimiter))
    {
        res.push_back(tmp);
    }
    return res;
}

string parseStringToTree(const string& str)
{
    stack<int> idxs;
    vector<string> vec(0);

    for (int i = 0; i < str.size(); ++i)
    {
        char c = str[i];
        if (c == '}')
        {
            // 如果遇到},则需要和最近的{匹配,而最近的{的索引就是idxs的栈顶值
            int idx = idxs.top();
            idxs.pop();
            string root = vec[idx - 1];
            string tmp = "";

            for (int j = idx + 1; j < vec.size(); ++j)
            {
                tmp = tmp + vec[j];
            }

            std::string left = "";
            std::string right = "";
            std::vector<std::string> parts = split(tmp, ',');
            if (parts.size() == 1)
            { // 对应c{f}这种没有右子节点的情况
                left = parts[0];
            }
            else
            {
                left = parts[0];
                right = parts[1];
            }

            vec.resize(idx - 1);
            vec.push_back(left + root + right);
            continue;
        }
        else if (c == '{')
        {
            idxs.push(vec.size());
        }

        string s = "";
        s.append(1,c);
        vec.push_back(s);
    }

    return vec[0];
}

int main()
{
    string str;
    cin >> str;

    cout << parseStringToTree(str);
    return 0;
}