劍指OFFER之樹的子結構(九度OJ1520)

題目描述:

輸入兩顆二叉樹A,B,判斷B是否是A的子結構。測試

 

輸入:

輸入可能包含多個測試樣例,輸入以EOF結束。
對於每一個測試案例,輸入的第一行一個整數n,m(1<=n<=1000,1<=m<=1000):n表明將要輸入的二叉樹A的節點個數(節點從1開始計數),m表明將要輸入的二叉樹B的節點個數(節點從1開始計數)。接下來一行有n個數,每一個數表明A樹中第i個元素的數值,接下來有n行,第一個數Ki表明第i個節點的子孩子個數,接下來有Ki個樹,表明節點i子孩子節點標號。接下來m+1行,與樹A描述相同。spa

 

輸出:

對應每一個測試案例,
若B是A的子樹輸出」YES」(不包含引號)。不然,輸出「NO」(不包含引號)。code

 

樣例輸入:
7 3
8 8 7 9 2 4 7
2 2 3
2 4 5
0
0
2 6 7
0
0
8 9 2
2 2 3
0
0

1 1
2
0
3
0

 

樣例輸出:
YES NO

 

提示:
B爲空樹時不是任何樹的子樹。

解題思路:

  這道題有個坑,首先題目要求n與m的範圍不能爲0,可是測試用例中第三個和第四個有可能分別是第一個樹空和第二個數空的特殊狀況。所以,要特別注意這裏,在scanf("%d %d",&n,&m)的時候對mn注意限制的範圍。blog

  另外用例並無給出單個葉子的狀況,這時注意,當輸入爲1時,只有一個節點,而且是左子樹節點。element

  例如當只有一個孩子時輸入的是input

  

孩子節點的數目 左邊孩子的編號

 

  另外就是這個題目的主要思想了。首先咱們採用的仍然是上次題目使用的結構的樹,主要思想就是遍歷左邊這顆樹的沒個元素,與右邊的樹進行比較。若是不一樣,就再比較左邊的孩子節點。一直到遍歷完全部的樹。it

  在進行比較時,判斷右邊的樹是否爲空,以及左邊的判斷頂點是否爲空,一旦發現比較的元素不一樣,就證實比較失敗。io

  主要的代碼,模仿書上代碼進行,本身寫的總出BUG,哎。class

int testForCompare(TreeArr *t1,int t1i,TreeArr *t2){ int result = 0; if(t1i != 0 && t2->arr[0].num != 0){ if(t1->arr[t1i].num == t2->arr[1].num) result = compare(t1,t1i,t2,1); if(!result) result = testForCompare(t1,t1->arr[t1i].lchild,t2); if(!result) result = testForCompare(t1,t1->arr[t1i].rchild,t2); } return result; }; int compare(TreeArr *t1,int t1i,TreeArr *t2,int t2i){ if(t2i == 0) return 1; if(t1i == 0) return 0; if(t1->arr[t1i].num != t2->arr[t2i].num) return 0; return compare(t1,t1->arr[t1i].lchild,t2,t2->arr[t2i].lchild)&&compare(t1,t1->arr[t1i].rchild,t2,t2->arr[t2i].rchild); }

所有代碼:

#include <stdio.h> #include <stdlib.h>
#define MAXSIZE 1005 typedef struct treeelement{ int num; int lchild; int rchild; }TreeElement; typedef struct treearr{ TreeElement arr[MAXSIZE]; }TreeArr; int testForCompare(TreeArr *t1,int t1i,TreeArr *t2); int compare(TreeArr *t1,int t1i,TreeArr *t2,int t2i); int main(void){ int n,m,i,nchild,n1,n2; TreeArr *t1 = (TreeArr *)malloc(sizeof(TreeArr)); TreeArr *t2 = (TreeArr *)malloc(sizeof(TreeArr)); while(scanf("%d %d",&n,&m) != EOF){ //....initialize the tree
        for(i=0;i<1000;i++){ t1->arr[i].num = 0; t1->arr[i].lchild = 0; t1->arr[i].rchild = 0; t2->arr[i].num = 0; t2->arr[i].lchild = 0; t2->arr[i].rchild = 0; } t1->arr[0].num = n; t2->arr[0].num = m; //.....input the first tree
        for(i=1;i<=n;i++){ scanf("%d",&t1->arr[i].num); } for(i=1;i<=n;i++){ scanf("%d",&nchild); if(nchild == 2){ scanf("%d %d",&n1,&n2); t1->arr[i].lchild = n1; t1->arr[i].rchild = n2; }else if(nchild == 1){//不肯定是怎麼輸入的?樣例中沒有這項
                scanf("%d",&n1); t1->arr[i].lchild = n1; }else if(nchild == 0){ } } //........input the second tree
        for(i=1;i<=m;i++){ scanf("%d",&t2->arr[i].num); } for(i=1;i<=m;i++){ scanf("%d",&nchild); if(nchild == 2){ scanf("%d %d",&n1,&n2); t2->arr[i].lchild = n1; t2->arr[i].rchild = n2; }else if(nchild == 1){//不肯定是怎麼輸入的?樣例中沒有這項
                scanf("%d",&n1); t2->arr[i].lchild = n1; }else if(nchild == 0){ } } //testing for compare
        if(testForCompare(t1,1,t2)) printf("YES\n"); else printf("NO\n"); } return 0; }; int testForCompare(TreeArr *t1,int t1i,TreeArr *t2){ int result = 0; if(t1i != 0 && t2->arr[0].num != 0){ if(t1->arr[t1i].num == t2->arr[1].num) result = compare(t1,t1i,t2,1); if(!result) result = testForCompare(t1,t1->arr[t1i].lchild,t2); if(!result) result = testForCompare(t1,t1->arr[t1i].rchild,t2); } return result; }; int compare(TreeArr *t1,int t1i,TreeArr *t2,int t2i){ if(t2i == 0) return 1; if(t1i == 0) return 0; if(t1->arr[t1i].num != t2->arr[t2i].num) return 0; return compare(t1,t1->arr[t1i].lchild,t2,t2->arr[t2i].lchild)&&compare(t1,t1->arr[t1i].rchild,t2,t2->arr[t2i].rchild); } /************************************************************** Problem: 1520 User: xhalo Language: C Result: Accepted Time:10 ms Memory:912 kb ****************************************************************/
相關文章
相關標籤/搜索