構建二叉樹並求其深度

/*題目描述:
輸入:
第一行爲整數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!

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