【劍指offer】樹的子結構
轉載請註明出處:http://blog.csdn.net/ns_code/article/details/25907685
劍指offer第18題,九度OJ上測試通過!
- 題目描述:
輸入兩顆二叉樹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描述相同。
- 輸出:
對應每個測試案例,
若B是A的子樹輸出”YES”(不包含引號)。否則,輸出“NO”(不包含引號)。
- 樣例輸入:
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為空樹時不是任何樹的子樹
在寫這道題目時,卡在了測試程式碼上,這個題目的測試程式碼有點繁雜,最後參考了一哥的文章,改用陣列作為儲存二叉樹節點的資料結構,果然寫測試程式碼方便了很多。
另外,程式中有一些要注意的地方,在程式中表明瞭註釋。
AC程式碼:
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct BTNode
{
int data;
int rchild;
int lchild;
}BTNode;
/*
判斷pTree2是否是與pTree1有共同的根節點的pTree1子樹
*/
bool isSubTree(BTNode *pTree1,int index1,BTNode *pTree2,int index2)
{
//前兩個if語句不能顛倒,不然當pTree1和pTree2相同時,會誤判為false
if(index2 == -1)
return true;
if(index1 == -1)
return false;
if(pTree1[index1].data != pTree2[index2].data)
return false;
else
return isSubTree(pTree1,pTree1[index1].lchild,pTree2,pTree2[index2].lchild) &&
isSubTree(pTree1,pTree1[index1].rchild,pTree2,pTree2[index2].rchild);
}
/*
判斷pTree1是否包含pTree2
*/
bool isContainTree(BTNode *pTree1,int index1,BTNode *pTree2,int index2)
{
if(pTree1==NULL || pTree2==NULL)
return false;
if(index1==-1 || index2==-1)
return false;
bool result = false;
if(pTree1[index1].data == pTree2[index2].data)
result = isSubTree(pTree1,index1,pTree2,index2);
//如果pTree1[index1].lchild為-1,下次遞迴時會通過index1==-1的判斷返回false,
//因此這裡不需要再加上pTree1[index1].lchild!=-1的判斷條件
if(!result)
result = isContainTree(pTree1,pTree1[index1].lchild,pTree2,index2);
if(!result)
result = isContainTree(pTree1,pTree1[index1].rchild,pTree2,index2);
return result;
}
int main()
{
int n,m;
while(scanf("%d %d",&n,&m) != EOF)
{
//輸入樹pTree1各節點的值
BTNode *pTree1 = NULL;
if(n>0)
{
pTree1 = (BTNode *)malloc(n*sizeof(BTNode));
if(pTree1 == NULL)
exit(EXIT_FAILURE);
int i,data;
//輸入n個節點的data
for(i=0;i<n;i++)
{
scanf("%d",&data);
pTree1[i].data = data;
pTree1[i].rchild = -1;
pTree1[i].lchild = -1;
}
//輸入n行節點連線關係
for(i=0;i<n;i++)
{
int ki;
scanf("%d",&ki);
if(ki == 0)
continue;
else if(ki == 1)
{
int lindex;
scanf("%d",&lindex);
pTree1[i].lchild = lindex-1;
}
else
{
int lindex,rindex;
scanf("%d",&lindex);
scanf("%d",&rindex);
pTree1[i].lchild = lindex-1;
pTree1[i].rchild = rindex-1;
}
}
}
//輸入樹pTree2各節點的值
BTNode *pTree2 = NULL;
if(m>0)
{
pTree2 = (BTNode *)malloc(m*sizeof(BTNode));
if(pTree2 == NULL)
exit(EXIT_FAILURE);
int i,data;
//輸入n個節點的data
for(i=0;i<m;i++)
{
scanf("%d",&data);
pTree2[i].data = data;
pTree2[i].rchild = -1;
pTree2[i].lchild = -1;
}
//輸入n行節點連線關係
for(i=0;i<m;i++)
{
int ki;
scanf("%d",&ki);
if(ki == 0)
continue;
else if(ki == 1)
{
int lindex;
scanf("%d",&lindex);
pTree2[i].lchild = lindex-1;
}
else
{
int lindex,rindex;
scanf("%d",&lindex);
scanf("%d",&rindex);
pTree2[i].lchild = lindex-1;
pTree2[i].rchild = rindex-1;
}
}
}
if(isContainTree(pTree1,0,pTree2,0))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
/**************************************************************
Problem: 1520
User: mmc_maodun
Language: C
Result: Accepted
Time:10 ms
Memory:912 kb
****************************************************************/
相關文章
- 劍指offer-17:樹的子結構
- 劍指offer面試18 樹的子結構面試
- 劍指offer——重建二叉樹二叉樹
- 【劍指offer】二叉樹深度二叉樹
- 《劍指offer》:[58]二叉樹的下一個結點二叉樹
- 劍指offer(四)重建二叉樹二叉樹
- 劍指Offer-40-二叉樹的深度二叉樹
- 劍指offer——二叉樹的映象C++二叉樹C++
- 【劍指offer】27. 二叉樹的映象二叉樹
- 劍指offer——二叉樹的深度C++二叉樹C++
- 《劍指offer》:[59]對稱的二叉樹二叉樹
- 《劍指offer》:[39]求解二叉樹的深度二叉樹
- 【劍指offer】連續子陣列的最大和陣列
- 劍指 Offer 07. 重建二叉樹二叉樹
- 【劍指offer】判斷二叉樹平衡二叉樹
- 劍指offer | 55 - I. 二叉樹的深度二叉樹
- 【劍指offer】字串的排列字串
- [劍指offer] 把二叉樹列印成多行二叉樹
- 《劍指offer》:[62]序列化二叉樹二叉樹
- 【劍指offer】5.二叉樹的映象和列印二叉樹
- 力扣 - 劍指 Offer 27. 二叉樹的映象力扣二叉樹
- 劍指 Offer 42.連續子陣列的最大和陣列
- 劍指Offer-連續子陣列中的最大和陣列
- 《劍指offer》:[60]把二叉樹列印成多行二叉樹
- 【劍指offer】從上向下列印二叉樹二叉樹
- 《劍指offer》:[52]構建乘積陣列陣列
- 【劍指offer】【2】字串的空格字串
- 【劍指offer】字串的組合字串
- PHPer也刷《劍指Offer》之連結串列PHP
- 劍指offer面試16 反轉連結串列面試
- # 劍指 Offer 68 - II. 二叉樹的最近公共祖先二叉樹
- 【劍指offer】【4】根據前序和中序結果,重建二叉樹二叉樹
- 《劍指Offer》- 連續子陣列的最大和或最小和陣列
- 劍指 Offer 48. 最長不含重複字元的子字串字元字串
- 劍指offer-例題 連續子陣列的最大和陣列
- JS資料結構與演算法 - 劍指offer二叉樹演算法題彙總JS資料結構演算法二叉樹
- 劍指offer-JavaScript版JavaScript
- 【劍指offer】左旋轉字串字串