Sweety

Practice makes perfect

导航

(二叉树递归)A - Tree Grafting(9.1.1)

Posted on 2014-07-30 19:07  蓝空  阅读(489)  评论(0编辑  收藏  举报

 

 

Description

Trees have many applications in computer science. Perhaps the most commonly used trees are rooted binary trees, but there are other types of rooted trees that may be useful as well. One example is ordered trees, in which the subtrees for any given node are ordered. The number of children of each node is variable, and there is no limit on the number. Formally, an ordered tree consists of a finite set of nodes T such that
  • there is one node designated as the root, denoted root(T);
  • the remaining nodes are partitioned into subsets T1, T2, ..., Tm, each of which is also a tree (subtrees).
Also, define root(T1), ..., root(Tm) to be the children of root(T), with root(Ti) being the i-th child. The nodes root(T1), ..., root(Tm) are siblings.

It is often more convenient to represent an ordered tree as a rooted binary tree, so that each node can be stored in the same amount of memory. The conversion is performed by the following steps:

  1. remove all edges from each node to its children;
  2. for each node, add an edge to its first child in T (if any) as the left child;
  3. for each node, add an edge to its next sibling in T (if any) as the right child.

This is illustrated by the following:

         0                             0
       / | \                          /
      1  2  3       ===>             1
        / \                           \
       4   5                           2
                                      / \
                                     4   3
                                      \
                                       5

In most cases, the height of the tree (the number of edges in the longest root-to-leaf path) increases after the conversion. This is undesirable because the complexity of many algorithms on trees depends on its height.

You are asked to write a program that computes the height of the tree before and after the conversion.

Input

The input is given by a number of lines giving the directions taken in a depth-first traversal of the trees. There is one line for each tree. For example, the tree above would give dudduduudu, meaning 0 down to 1, 1 up to 0, 0 down to 2, etc. The input is terminated by a line whose first character is #. You may assume that each tree has at least 2 and no more than 10000 nodes.

Output

For each tree, print the heights of the tree before and after the conversion specified above. Use the format:

 Tree t: h1 => h2 
where t is the case number (starting from 1), h1 is the height of the tree before the conversion, and h2 is the height of the tree after the conversion.

Sample Input

dudduduudu
ddddduuuuu
dddduduuuu
dddduuduuu
#

Sample Output

Tree 1: 2 => 4

Tree 2: 5 => 5

Tree 3: 4 => 5

Tree 4: 4 => 4

 

在开始做的时候也是没有什么思路,从网上找了点思路其实想想就是一个递归。

但是在做本题时要注意由普通的树转化为二叉树的规则:左儿右兄

就是将一个节点的第一个儿子放在左儿子的位置,下一个的儿子,即左儿子的第一个兄弟,
放在左儿子的右儿子位置上,再下一个兄弟接着放在右儿子的右儿子.

由于多叉树转二叉树的方法是"左儿子右兄弟",因此 二叉树中X节点的高=二叉树中X的父节点的高+X是第几个儿子

形成了一个递归定义. 可以用递归算法解决.

 

其实u在这没有什么实质性的作用,只是代替一个字符,而查找的是d并且通过一个while来统计变化前和变化后的height

另外再出现一次!'d'时,就会相当于当前的递推就中断一次,出现一次返回,这就相当于是将树向上一级,达到题意的效果

并且tempson是记录当前位置的父节点下有多少儿子的

这道题如果是用单纯的for或者是while的话,一定会很麻烦,因为需要记录下当前节点的信息,并且要开辟好几个数组,这样麻烦就大了。。。

 

#include <iostream>
#include <string>
using namespace std;
string s;
int i,n=0,height1,height2;

void find(int level1,int level2)//第一个变量是用来测改变前的,第二个是用来测改变后的
{
 int tempson=0;
 while (s[i]=='d')
 {
  i++; 
  tempson++;       //tempson是记录这是第几个儿子的
  find(level1+1,level2+tempson);</span>  //递归更新查找最大的高度     
 }
if(level1>height1)
     height1=level1;
 if( level2>height2)
     height2=level2;
 i++;

int main()
{
 cin>>s;
 while (s!="#")
 {
  i=height1=height2=0;
  find(0,0);
  cout<<"Tree "<<++n<<": "<<height1<<" => "<<height2<<endl;
  cin>>s;
 }
 return 0;
}