照例先上題目
7:樹的轉換
- 總時間限制:
- 5000ms
- 內存限制:
- 65536kB
- 描述
-
我們都知道用“左兒子右兄弟”的方法可以將一棵一般的樹轉換爲二叉樹,如:
0 0 / | \ / 1 2 3 ===> 1 / \ \ 4 5 2 / \ 4 3 \ 5
現在請你將一些一般的樹用這種方法轉換爲二叉樹,並輸出轉換前和轉換後樹的高度。
- 輸入
- 輸入包括多行,最後一行以一個#表示結束。
每行是一個由“u”和“d”組成的字符串,表示一棵樹的深度優先搜索信息。比如,dudduduudu可以用來表示上文中的左樹,因爲搜索過程爲:0 Down to 1 Up to 0 Down to 2 Down to 4 Up to 2 Down to 5 Up to 2 Up to 0 Down to 3 Up to 0。
你可以認爲每棵樹的結點數至少爲2,並且不超過10000。 - 輸出
- 對於每棵樹,按如下格式輸出轉換前和轉換後樹的高度:
Tree t: h1 => h2
其中t是樹的編號(從1開始),h1是轉換前樹的高度,h2是轉換後樹的高度。 - 樣例輸入
-
dudduduudu ddddduuuuu dddduduuuu dddduuduuu #
- 樣例輸出
-
Tree 1: 2 => 4 Tree 2: 5 => 5 Tree 3: 4 => 5 Tree 4: 4 => 4
- 題目描述一棵樹的方式是先根遍歷。設置一個棧,用於保存父結點,棧底壓入整棵樹的根結點;棧頂結點始終是當前的父結點。掃描輸入字符串,遇到'd',從棧頂取出父結點FA,新建一個結點SON作爲FA的兒子,鏈接起來,並將SON壓入棧中,作爲新的父結點備用;遇到'u',執行彈棧操作,回溯到上一個父結點。在此過程中,棧可達到的最大尺寸-1就是樹的高度。
- 根據“左子右兄(left child right sibling)”的規則,當爲FA添加兒子時,若FA->lchild爲空,那麼此時SON是FA的第一個兒子,FA->lchild=SON,若FA->lchild不爲空,那麼SON是FA->lchild的弟弟,要添加到FA->lchild右子鏈的最末端。
- 採用遞歸計算轉換後的二叉樹的高度。
#include <iostream>
using namespace std;
#include <stack>
#define MAXN 20010
typedef struct _tnode
{
int info;
struct _tnode *lmchild;
struct _tnode *rsibling;
} tnode;
stack<tnode *> rootstack;
tnode *build_bin_tree(char inputseq[], tnode *root, int *max_stack_sz)
{
char *p=inputseq;
int val=1;
tnode *father, *temp, *current;
while( *p != '\0' )
{
if (*p == 'd') //一個新的結點
{
temp=new tnode;
temp->info=(val++);
temp->lmchild=NULL;
temp->rsibling=NULL;
father=rootstack.top();
//temp現在是father的兒子,那麼,它是father的left-most-child(lmc)呢,還是lmc的right sibling呢?
if(father->lmchild == NULL) //是father的lmc
{
father->lmchild=temp;
}
else //是lmc的right sibling
{
current=father->lmchild;
while (current->rsibling != NULL) current=current->rsibling;
current->rsibling=temp;
}
rootstack.push(temp);
if(rootstack.size() > (*max_stack_sz)) (*max_stack_sz)=rootstack.size(); //記錄棧的最大尺寸
}
else
{
rootstack.pop();
}
++p;
}
return root;
}
int bin_tree_layer(tnode *root) //遞歸計算轉換後二叉樹的層數
{
int left_h, right_h;
if(root==NULL) return 0;
else
{
left_h = 1 + bin_tree_layer(root->lmchild);
right_h = 1 + bin_tree_layer(root->rsibling);
if (left_h > right_h) return left_h;
else return right_h;
}
}
void delete_bin_tree(tnode *root)
{
if (root != NULL)
{
delete_bin_tree(root->lmchild);
delete_bin_tree(root->rsibling);
delete root;
root=NULL;
}
}
int main()
{
//freopen("D:\\in.txt", "r", stdin);
//freopen("D:\\out.txt", "w", stdout);
tnode *root;
int max_stack_sz, bt_layers, serial=0;
char inputseq[MAXN];
while (1)
{
cin.getline(inputseq, MAXN, '\n');
if(inputseq[0] == '#') break;
//初始化
++serial;
root=new tnode;
root->info=0;
root->lmchild=NULL;
root->rsibling=NULL;
while(!rootstack.empty()) rootstack.pop();
rootstack.push(root);
max_stack_sz=1;
//處理
root = build_bin_tree(inputseq, root, &max_stack_sz);
bt_layers = bin_tree_layer(root);
cout<<"Tree "<<serial<<": "<<(max_stack_sz-1)<<" => "<<(bt_layers-1)<<endl;
//收尾工作
delete_bin_tree(root);
}
return 0;
}