清华机试-二叉树遍历
题目描述
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: 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; }