1043. 完全二叉樹(上海交大OJ)
阿新 • • 發佈:2018-12-12
1043. 完全二叉樹
Description
給出一棵二叉樹,判斷其是否為完全二叉樹。
Input Format
第一行,N<1000000,表示二叉樹節點數。
預設序號為0的節點為樹根。接下來共N-1行,依次表示序號為1,...,N-1的節點的父親節點序號。
如果一個節點有兩個孩子節點,左孩子節點序號總是小於右孩子節點序號。
Output Format
僅一行,如果是完全二叉樹,則輸出true,否則輸出false。
Hint
Sample Input1
6
0
1
1
0
4
Sample Output1
true
Sample Input2
6
0
1
1
0
3
Sample Output2
false
思路:用結構體儲存結點資訊,因為是完全二叉樹,所以根據完全二叉樹的性質,n為結點數,深度K=(log2(n)向下取整)+1;
葉子結點數(無左右孩子的結點) =n+1-Pow(2,k-1);
程式碼如下:
#include<iostream> #include<algorithm> #include<cmath> using namespace std; int cnt1=1,cnt2=1,n; struct Tree { int Lchild; int Rchild; }; Tree a[1000000]; void Treedef()//初始化樹 { for(int i=0;i<100000;i++) { a[i].Lchild=0; a[i].Rchild=0; } } int find1(int x)//因為左結點序號小於右結點 { for(int i=x;i<a[0].Rchild;i++) { if(a[i].Lchild!=0 || a[i].Rchild!=0) { cnt1++; } } return cnt1+1; } int find2(int y) { for(int i=y;i<n;i++) { if(a[i].Lchild!=0 || a[i].Rchild!=0) { cnt2++; } } return cnt2+1; } int cmp(int a,int b)//找出最大子深度 { if(a>b) { return a; } if(a<b) { return b; } if(a==b) { return a; } } int main() { Treedef(); int m,num=1,cnt=0; cin>>n; for(int i=0;i<n-1;i++) { cin>>m; if(a[m].Lchild!=0) { a[m].Rchild=num++; } else { a[m].Lchild=num++; } } int k=log10(n)/log10(2)+1;//計算樹的深度 int mac=cmp(find1(a[0].Lchild),find2(a[0].Rchild));//找出左右子樹的最大深度 for(int i=0;i<n;i++)//統計葉子結點數 { if(a[i].Lchild==0&&a[i].Rchild==0) { cnt++; } } if(cnt==(n+1-pow(2,k-1)) &&mac-1==k)//判斷是否為完全二叉樹 { cout<<"true"; } else { cout<<"false"; } return 0; }
雖然AC了,但是程式碼不夠好;有好想法的朋友歡迎探討!!!;