一开始没思路, 后来看到有人一句话概述了方法, 然后自己捉摸了一下, 就想到了.
只要大家把输入倒着看, 就是一个先遍历根节点右子树再遍历左子树的" 先序遍历", 叶子就是小写字母, 然后输出就是层次输出, 但顺序是倒着的, 所以我用栈存储最后的答案.
估计大家看着也不是很明白, 不过只要把Sample Data画一下就很直观了, 也可以参考一下这篇文章, 树画出来的样子如下, 只不过他的方法太复杂了, 用并树来建树.
优快云说有被禁用的URL... 等我联系了客服再加上链接.. 话说最近优快云老出问题.(╯‵□′)╯ ┴─┴
因为题目说输入可能有10000, 为了避免浪费空间一咬牙用string写了... 然后就习惯性加上了printf, CE了一次...
详情见代码
#include <iostream>
#include <string>
#include <cctype>
#include <queue>
#include <stack>
using namespace std;
struct Node
{
char c;
Node *left, *right;
Node(char v)
{
left = right = 0;
c = v;
}
};
stack<char> ans;
queue<Node *> scan;
string str;
int i;
Node *Build();
void BFS(Node *root);
void Output();
int main()
{
//freopen("input.txt", "r", stdin);
int n;
cin >> n;
while (n--)
{
cin >> str;
i = str.size() - 1;
//建树.
Node *root = Build();
//层次遍历输出.
scan.push(root); //先把根节点放入队列.
BFS(root);
Output();
}
return 0;
}
Node *Build()
{
Node *root = new Node(str[i]);
if (islower(str[i])) //如果当前值是小写字母, 说明没有左右子树了.
{
i--;
return root;
}
i--;
root->right = Build();
root->left = Build();
return root;
}
void BFS(Node *root)
{
Node *now;
while (!scan.empty())
{
now = scan.front();
if (scan.front()->left) //如果当前结点有左子树. 因为有左子树必有右子树.
{
ans.push(now->left->c); //接下来两个结点进栈.
ans.push(now->right->c);
scan.push(now->left); //放队列里
scan.push(now->right);
scan.pop(); //当前结点出队.
}
else
scan.pop(); //不然的话当前结点就是小写字母, 直接出队.
}
}
void Output()
{
while (!ans.empty())
{
cout << ans.top();
ans.pop();
}
cout << str[str.size() - 1];
cout << endl;
}