/*题目描述:
输入:
第一行为整数n(n >= 2),表示二叉树节点总数
后面带n-1行,每行为整数a和整数b的输入格式,a表示父亲节点,b表示a的一个子节点
输出:
二叉树的深度
示例输入:
5
0 1
0 2
1 3
1 4
输出:
3
*/
#include <iostream>
#include <cstdio>
using namespace std;
//节点数据结构
class Node
{
public:
int value;
Node *left;
Node *right;
Node(int value)
{
this->value = value;
left = NULL;
right = NULL;
}
};
//父子关系的链接
void link(Node *first, Node *next)
{
if(first == NULL)
return;
if(first->left == NULL)
first->left = next;
else
first->right = next;
}
//根据value值定位节点指针
Node *findNode(Node *root, int value)
{
if(root == NULL)
return NULL;
if(root->value == value)
return root;
if(root->left != NULL)
{
Node *temp = findNode(root->left, value);
if(temp != NULL)
return temp;
}
else
{
Node *temp = findNode(root->right, value);
if(temp != NULL)
return temp;
}
}
//求二叉树深度
int maxDeep(Node *root)
{
if(root == NULL)
return 0;
int max1 = maxDeep(root->left) + 1;
int max2 = maxDeep(root->right) + 1;
return (max1 > max2) ? max1 : max2;
}
int main()
{
int n;
cin>>n;
n--;
int a, b;
Node *root = NULL;
while(n--)
{
cin>>a>>b;
if(root == NULL)
{
root = new Node(a);
Node *newNode = new Node(b);
link(root, newNode);
}
else
{
Node *node1 = findNode(root, a);
Node *newNode2 = new Node(b);
link(node1, newNode2);
}
}
int result = maxDeep(root);
cout<<result<<endl;
return 0;
}
我的这个解法可能略复杂,不过思路是我按照分治法或者更确切地说Top down design思想设计的,所以训练价值颇高。
分析题目,缕清一个大致流程,可以知道有两个关键大步骤:
1.根据输入构造一棵二叉树,这里可以设计成一个函数
然后这步可以细化一下:
(1)把节点抽象成一个数据结构(class)Node方便操作,每个Node都包含一个value值和一个指向左子树的指针和指向右子树的指针
(2)从根节点开始构建二叉树,首次输入,需要new出两个节点出来,然后构建好链接关系(link函数)
(3)除首次输入(建立根节点那次)之外,其余的每行输入父节点都是已经new出来了的节点,所以需要有个根据value值查找旧节点的过程(findNode函数),然后将查找到的这个旧节点与新new出来的节点link起来
(4)构造完毕,把指向根节点的root指针传进求二叉树深度的函数去求深度
2.后面就是经典的题目:给定root节点指针求二叉树深度了
我个人领悟的Top down design入门的一个关键思想是:
(1)把任务拆分成几个关键步骤,然后把这几个关键步骤弄成一个函数(先写个定义没实现的函数),先把main函数里面的代码搞定,也就是把关键技术抽取到外面去解决,先不管它,先在main函数里面把算法框架搭好。
(2)至于那些关键函数怎么搞定?继续拆,如果太庞大,则继续拆分成若干个子函数去解决,这里运用分治法的思想。
(3)分而治之之后,逐个小函数进行攻破,把所有函数都给实现,这里看的就是编程功底了,一般有一些火候的,不难的话总能搞定,即便所花的时间比较久。
生动点来说就是:
现在有门生意/大项目,
(1)你是老板,首先接了这个大项目,然后把它拆成几个关键性模块,这些模块暂时只是个空的框架,然后你把这些空框架组合在main函数里面,然后把这些模块分给A组、B组、C组的研发组去搞定,老板这里不care实现,因为老板相信研发组肯定能给我搞定的,当ABC三组的各自模块被实现之后,我前面的总框架就被激活了,大项目也就盘活了。
(2)然后你从老板化身为A组研发人员了,你的coding功底很棒,迅速把A组所属的模块给实现了(或者你再把任务拆分成更小的子模块去交给另外的人搞);然后你又化身为B组研发人员,同样去搞定了分配的模块,以此类推。
(3)当A、B、C三组的模块都实现了之后,你再化身回老板,此时发现所谓的大项目已经被解决了,然后修饰一下,就可以交付这个生意了……
虽然身份转换始终都是同一个人在干,但是当你将分拆的小任务一个个完成,累积到上面成一个更大的丰硕成果,成就感倍增有木有,打鸡血了有木有,斗志来了有木有,coding也快了很多有木有,最后愉快地提交了代码发现accept通过了有木有很high!