构建二叉树并求其深度

/*题目描述:
输入:
第一行为整数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!

posted @ 2016-09-24 00:35  Victor_Lv  阅读(316)  评论(0编辑  收藏  举报