牛客網在線編程題——樹的高度(2)
阿新 • • 發佈:2018-11-23
有一個 兩種 turn lse 深度 while vector 構造二叉樹 出發
題目描述
現在有一棵合法的二叉樹,樹的節點都是用數字表示,現在給定這棵樹上所有的父子關系,求這棵樹的高度輸入描述:
輸入的第一行表示節點的個數n(1 ≤ n ≤ 1000,節點的編號為0到n-1)組成, 下面是n-1行,每行有兩個整數,第一個數表示父節點的編號,第二個數表示子節點的編號
輸出描述:
輸出樹的高度,為一個整數示例1
輸入
5 0 1 0 2 1 3 1 4
輸出
3
兩種解題思路:
1、用輸入數據構造二叉樹,根據二叉樹再求樹的高度;
2、根據一個節點只有一個父節點的思路求解(需要考慮非法二叉樹的情況)。
第一種思路的解題代碼(參考代碼:https://blog.csdn.net/qq_40269087/article/details/80443682):
#include<iostream> #include<malloc.h> using namespace std; typedef struct BiTreeNode//定義節點結構 { int data; struct BiTreeNode *lchild,*rchild; }BiTreeNode,*BiTree; void CreateBiTree(BiTree T, int x, int y)//構造二叉樹 { BiTree t; if(T) { if(T->data==x){if(T->lchild==NULL) { t=(BiTree)malloc(sizeof(BiTreeNode)); t->data=y; t->lchild=NULL; t->rchild=NULL; T->lchild=t; }else if(T->rchild==NULL) { t=(BiTree)malloc(sizeof(BiTreeNode)); t->data=y; t->lchild=NULL; t->rchild=NULL; T->rchild=t; } }else { CreateBiTree(T->lchild,x,y); CreateBiTree(T->rchild,x,y); } } } int Depth(BiTree T)//求樹的深度 { if(T==NULL){ return 0; }else{ int m=Depth(T->lchild); int n=Depth(T->rchild); if(m>n){ return m+1; }else{ return n+1; } } } int main(){ int n,a,b; cin>>n; BiTree root; root=(BiTree)malloc(sizeof(BiTreeNode)); root->data=0; root->lchild=NULL; root->rchild=NULL; for(int i=0;i<n-1;i++){ cin>>a>>b; CreateBiTree(root,a,b); } cout<<Depth(root)<<endl; return 0; }
值得學習的點:1、構造二叉樹的關鍵點①找到待插入節點的父節點②確定是插入到左子樹還是右子樹。
2、構造二叉樹和求解二叉樹的深度都是采用遞歸的方法,思想可以借鑒,但是需要註意遞歸算法的通病:比較耗時。
3、輸入數據時,采用二叉樹存儲數據。值得思考的問題是在解答問題先,需要先考慮好使用什麽數據結構來存儲輸入數據,這樣會促使自己去把具體問題,與數據結構相結合,有助於加快解題。
第二種解題思路的代碼(參考代碼:https://www.nowcoder.com/discuss/11934?type=1&pos=&page=1 評論中的第12樓):
#include<iostream> #include<vector> using namespace std; int main() { int n,a,b; cin>>n; int nodeindex[n]; bool flag[n];//節點有效性標誌 for(int i=0;i<n;i++)//初始化 { nodeindex[i]=-1; flag[i]=true; } for(int i=0;i<n-1;i++) { cin>>a>>b; int count=0; for(int j=0;j<n;j++) { if(nodeindex[j]==a) { count++; } } if(count<2)//合法二叉樹 { if(flag[a]==true) { nodeindex[b]=a;//數組中的下標為子節點,值為父節點 }else//但是父節點無效,所以其對應的子節點也無效 { flag[b]=false; } }else//同一個父節點上的子節點數目大於2,為非法二叉樹,將多余子節點置為無效節點 { flag[b]=false; } } int max=0; int count=0; for(int i=0;i<n;i++)//遍歷所有的節點,以該節點出發,求對應的樹的高度 { if(flag[i])//篩除掉無效節點 { int cur=i; while(cur!=-1) { cur=nodeindex[cur]; count++; } if(count>max) { max=count; } count=0; } } cout<<max; return 0; }
值得學習的點:1、所有的節點都只對應了唯一一個父節點,利用這種思路可以避開根據輸入數據生成二叉樹的步驟;
2、需要排除非法二叉樹的情況,就是一個父節點下有超過2個的子節點,選用合適的標誌,排除非法情況。
兩種思路的比較:
1、個人更加贊同使用思路1中的方法,因為該方法更加的傳統,使用性更廣泛,關鍵是在短的時間裏很容易想到;
2、方法二就顯得十分的巧妙,思路短時間難以形成,並且需要自己去排除非法二叉樹的情況(這也是題目比較坑的地方,很多參考代碼都沒有將這點考慮進去,最終只能達到50%的通過案例)。
牛客網在線編程題——樹的高度(2)