openjudge樹的轉換

照例先上題目

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










































  1. 題目描述一棵樹的方式是先根遍歷。設置一個棧,用於保存父結點,棧底壓入整棵樹的根結點;棧頂結點始終是當前的父結點。掃描輸入字符串,遇到'd',從棧頂取出父結點FA,新建一個結點SON作爲FA的兒子,鏈接起來,並將SON壓入棧中,作爲新的父結點備用;遇到'u',執行彈棧操作,回溯到上一個父結點。在此過程中,棧可達到的最大尺寸-1就是樹的高度。
  2. 根據“左子右兄(left child right sibling)”的規則,當爲FA添加兒子時,若FA->lchild爲空,那麼此時SON是FA的第一個兒子,FA->lchild=SON,若FA->lchild不爲空,那麼SON是FA->lchild的弟弟,要添加到FA->lchild右子鏈的最末端。
  3. 採用遞歸計算轉換後的二叉樹的高度。
代碼清單
#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;
}


發佈了50 篇原創文章 · 獲贊 16 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章