思路:給出了二叉樹的先序遍歷,首先我們得根據先序遍歷來建樹,然後,我們來觀察這個輸出的樹型,我們發現,將所有字母全部排列在一行,就變成了這棵二叉樹的中序遍歷(比如這個例題的輸出,一行排列就是
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;
}
代碼可能寫的有點亂,有好建議的童靴也可以在評論區提出,一起學習!
參考創建博客:先序創建