- 从先序遍历还原二叉树
我们从二叉树的根节点 root 开始进行深度优先搜索。
在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。
如果节点只有一个子节点,那么保证该子节点为左子节点。
给出遍历输出 S,还原树并返回其根节点 root。
思路:
因为给出的是先序遍历的二叉树,按照这个顺序重建二叉树,就需要将每个子树的根节点记录下来。
这里使用了一个栈来保存根节点的指针和深度。新节点加入二叉树中,需要从栈找到父节点,根据深度进行判断(深度相差1),就是一个单调栈,深度总是增加的。
TreeNode* recoverFromPreorder(string S) {
//构造树,需要记录每层的节点,
S+='-'; //为了将最后一个数加入树中,不用多做处理
TreeNode* root;
int i = 0;
int num = 0;
while(i < S.size())
{
if(S[i]!='-')
{
num = num*10 + S[i]-'0';
}
else
{
break;
}
i++;
}
root = new TreeNode(num);
bool flag = false; //false 记录-, true 记录数字
int count = 0; //记录长度-
stack<pair<TreeNode*, int>> rec;
rec.push(pair<TreeNode*,int>(root, 0));
while(i < S.size())
{
if(flag)
{
if(S[i]=='-')
{
flag = false;
//新节点
TreeNode* node = new TreeNode(num);
pair<TreeNode*, int> pre = rec.top();
while(pre.second+1!= count)
{
rec.pop();
pre = rec.top();
}
if(pre.second + 1 == count)
{
if(pre.first->left)
{
pre.first->right = node;
rec.push(pair<TreeNode*,int>(node, count));
}
else
{
pre.first->left = node;
rec.push(pair<TreeNode*,int>(node, count));
}
}
count=0;
i--;
}
else
{
num = num*10 + S[i]-'0';
}
}
else
{
if(S[i]!='-')
{
flag = true;
num = 0;
i--;
}
else
{
count++;
}
}
i++;
}
return root;
}