题目描述
输入一串二叉树,用遍历前序打出。
输入格式
第一行为二叉树的节点数n(n≤26)。
后面n行,每一个字母为节点,后两个字母分别为其左右儿子,空节点用*表示。
保证:读入的第一个结点就是根结点。
输出格式
前序排列的二叉树。
样例输入
6
abc
bdi
cj*
d**
i**
j**
样例输出
abdicj
分析
题最终目的是输出二叉树的前序遍历结果。首先回顾下前序遍历的形式:
- 遍历根节点
- 前序遍历左子树
- 前序遍历右子树
从描述中能发现很明显的递归结构,大致结构伪代码:
void frontOrder(root){
//遍历根节点
cout<<root.val<<" ";//输出根节点信息
//前序遍历左子树
frontOrder(root.leftChild);
//前序遍历右子树
frontOrder(root.rightChild);
}
继续分析,现在欠缺的是二叉树的建立。观察输入格式,它是以小写字母代表各结点,用'*'表示空节点。
如果用数组存储结点信息,为了方便字母与结点位置的对应我们可以利用ASCII码值的差值与连续性,将小写字母减去'a'从而对应上数字0 ~ 25。正好用这些数字与数组下标产生映射。
int num=c-'a';//小写字母对应上 0 ~ 25
过程中需要注意空节点的处理,以及根节点的信息记录。
参考代码
#include <iostream>
using namespace std;
int n;
struct node{
int li,ri;
}dot[30];
void dfs(int x){
if(x==-1) return ;
//前序遍历 根 左 右
//遍历根节点
cout<<char(x+'a');//将0~25再转成a~z
//遍历左子树
dfs(dot[x].li);
//遍历右子树
dfs(dot[x].ri);
}
int main(){
char a,l,r;
int root;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a>>l>>r;//输入节点关系
//为了进行节点的快速处理,将'a'~'z'转成对应0~25 '*'转成-1
int idx=a-'a';
if(i==1) root=idx;//记录根节点
if(l=='*')
dot[idx].li=-1;
else
dot[idx].li=l-'a';
if(r=='*')
dot[idx].ri=-1;
else
dot[idx].ri=r-'a';
}
dfs(root);
return 0;
}