思路:给出了二叉树的先序遍历,首先我们得根据先序遍历来建树,然后,我们来观察这个输出的树型,我们发现,将所有字母全部排列在一行,就变成了这棵二叉树的中序遍历(比如这个例题的输出,一行排列就是
CBDAGEHKF),输出是按行来进行的,这时候我们就会想到来根据层序遍历来逐层打印树的结点,具体看代码
#include<bits/stdc++.h>
using namespace std;
typedef char ElementType;
typedef struct Node
{
ElementType data;
struct Node *lchild;
struct Node *rchild;
}BTNode,*BTree;
int cc=0,sum=0;
char zm[101];
BTree createTree(char *s) //先序遍历来建树
{
if(*(s+cc)=='.')
{
cc++;
return NULL;
}
BTree boot=new Node;
boot->data=*(s+cc);
cc++;
boot->lchild=createTree(s);
boot->rchild=createTree(s);
return boot;
}
void midbl(BTree bt) //中序遍历这棵树,把中序得出的节点字母存储
//到一个数组中,数组的下标就是这个节点数据输出的位置距离最左端的长度减1
{
if(bt==NULL) return;
midbl(bt->lchild);
zm[++sum]=bt->data;
midbl(bt->rchild);
}
char dp[101][101]; //二维数组表示第几行第几个节点的数据
int c1=1,bj=0; //c1指树型的行数,bj指某行节点数据输出时前面已经被占据的
//位置的数量,可以这么说吧,比如我要输出字母X,zm[i]=x,本来是在X的前面输出
//i-1个“-”,但这一行X的前面已经有bj个列数被其他字母占据了,所以实际输出
//i-bj个“-”(为什么不是i-bj-1,因为bj初始为1)
void layerOrder(BTree bt) //层序遍历
{
BTree t;
queue<BTree> q;//为了进行层序遍历
queue<BTree> mid;//为了输出换行而设置的传递队列,具体看代码理解
q.push(bt);
while(!q.empty())
{
t=q.front();
q.pop();
bj=1;
for(int i=1;i<=sum;i++)
{
if(zm[i]==t->data)
{
dp[c1][i]=t->data;
for(int j=i-1;j>=1;j--)
if(isalpha(dp[c1][j]))
{bj+=j;break;}
i-=bj;
while(i--) cout<<"-";
cout<<t->data;
break;
}
}
if(t->lchild!=NULL)
mid.push(t->lchild);
if(t->rchild!=NULL)
mid.push(t->rchild);
if(q.empty()) //一行节点数据打印完就要开始换行
{
cout<<endl;
c1++;
while(!mid.empty())
{
q.push(mid.front());
mid.pop();
}
}
}
}
int main()
{
char s[106];
gets(s);
BTree r = createTree(s);
midbl(r);
layerOrder(r);
return 0;
}
代码可能写的有点乱,有好建议的童靴也可以在评论区提出,一起学习!
参考创建博客:先序创建