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