1. 程式人生 > >判斷一顆樹是否為完全二叉樹

判斷一顆樹是否為完全二叉樹

題目連結:https://oj.ismdeep.com/contest/problem?id=1396&pid=7

H: CBT?

時間限制: 1 s      記憶體限制: 128 MB        我的狀態

題目描述

對於二叉樹,如果這棵樹的節點排布是按行從上到下,每行從左到右挨個放置,中間不會有空閒的節點。則我們稱之為完全二叉樹。

注:這棵樹的根節點的值一定是1

輸入

輸入數字正整數n (

≤n≤20">1n201≤n≤20)

接下來n行,每行為兩個數字(a,b)和一個字元c(L 或者 R),如果字元c是L,則表示b是a的左子節點;如果字元c是R,則表示b是a的右子節點。 (1a,b30001≤a,b≤3000)

輸出

判斷這棵樹是否為完全二叉樹,如果是則輸出Yes,否則輸出No

樣例輸入

5
1 2 L
1 3 R
2 4 L
2 5 R
3 6 L

樣例輸出

Yes

提示

樣例解釋:樣例所描述的二叉樹結構如下

很顯然這是一個完全二叉樹。

這題wa了很多發,最後總算是改出來了,具體思路程式碼:

#include<iostream>
#include<math.h>
#include<string.h>
#include<stdio.h>
#include<queue>
using namespace std;
const int maxn=3000+5;
struct p
{
    int l=0,r=0;
};
queue<p>q;
int a[maxn][2];//a[i][0]代表i的左兒子的值 a[i][1]代表i的右兒子的值
void solve()
{
    p q1;
    
if(a[1][0]!=0) q1.l=a[1][0]; if(a[1][1]!=0) q1.r=a[1][1]; q.push(q1);//把根節點入佇列 while(!q.empty()) { int flag=0; q1=q.front(); q.pop(); if(q1.l==0&&q1.r!=0)//左兒子為空 右兒子卻不為空 肯定不是完全二叉樹 { cout<<"No"<<endl; return ; } if((q1.l!=0&&q1.r==0)&&(!q.empty()))//左兒子不為空 右兒子為空 但是佇列卻不為空 { cout<<"No"<<endl; return ; } if(q1.l!=0) { p q2;//把左兒子入佇列 int s=q1.l; if(a[s][0]!=0) q2.l=a[s][0]; if(a[s][1]!=0) q2.r=a[s][1]; if(q2.l!=0||q2.r!=0)//注意!!! 就是因為這裡wa了好幾發 因為我要把一個節點入隊 肯定要該節點有值 不然入了個空節點就錯了 q.push(q2); else flag=1; } if(q1.r!=0) { p q2; int s=q1.r; if(a[s][0]!=0) q2.l=a[s][0]; if(a[s][1]!=0) q2.r=a[s][1]; if(q2.l!=0||q2.r!=0) { if(flag==1)//左兒子為空 右兒子卻不為空 { cout<<"No"<<endl; return ; } q.push(q2); } } } cout<<"Yes"<<endl; } int main() { int n,l,r; char c; memset(a,0,sizeof(a)); cin>>n; for(int i=0;i<n;i++) { cin>>l>>r>>c; if(c=='L') a[l][0]=r; else a[l][1]=r; } solve(); return 0; }