题目描述
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
输入描述:
输入包括1行字符串,长度不超过100。
输出描述:
可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行。
示例1
输入
abc##de#g##f###
输出
c b e g d f a
解题思路
题目主要分为两个步骤:1. 根据字符串构建二叉树;2.根据二叉树进行中序遍历。
构建二叉树的过程如下:
每次读取一个字符,如果当前字符是#,则将当前指针设置为NULL,结束当前树的构造;
如果不是#,则new一个节点,将字符存进节点,并将指针指向该节点,接下来,分别构建左子树和右子树。
中序遍历过程如下:
1.先遍历左子树;2.取当前节点的值;3.遍历右子树。
做题的时候link(struct Node* &p,int index)函数p前面少了一个&符号,这样子构建完其实左右子树并没有链接到双亲节点。尤其要注意指针引用与指针的区别,前者会改变传参进来的指针指向哪个对象,后者一般用来改变原有指向的对象。
代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Node{
struct Node* left;
struct Node* right;
char c;
};
string s;
void link(struct Node* &p,int &index)
{
if(s[index] == '#')
{
p = NULL;
index++;
}
else
{
struct Node *now = new struct Node; //生成当前节点
now->left = NULL;
now->right = NULL;
now->c = s[index];
p = now;
index++;
link(p->left,index); //生成左子树
link(p->right,index); //生成右子树
}
}
vector<char> v;
void se(struct Node* p)
{
if(p == NULL) return;
se(p->left); //遍历左子树
v.push_back(p->c); //取中间节点
se(p->right); //遍历右子树
}
int main()
{
while(cin >> s)
{
int index = 0;
struct Node *first = new struct Node;
link(first,index);
vector<char> temp;
v.swap(temp);
se(first);
int v_len = v.size();
for(int i = 0;i < v_len;i++)
{
cout << v[i] << " ";
}
cout << endl;
}
return 0;
}