題目:輸入兩棵二叉樹 A 和 B,判斷 B 是否是 A 的子結構。如圖:ios
A B測試
分析:要查找樹 A 中是否存在和樹 B同樣的子樹。能夠分爲兩步:① 在樹 A 中找到和樹 B 的根節點的值同樣的節點 R; ② 再判斷樹 A 中以 R 爲根節點的子樹是否包含和樹 B 同樣的結構。spa
以上面的兩棵樹爲例,首先在樹 A 中找到值爲 8 (樹 B的根節點的值) 的節點。從樹 A的根節點開始遍歷,發現根節點的值就是 8,接着去判斷樹 A 的根節點下面的子樹是否含有與樹 B 相同的結構。在樹 A 中,根節點的左孩子爲 8,而樹 B 的根節點的左孩子爲 9,對應的兩個節點不一樣。所以,仍然須要遍歷樹 A,繼續查找節點值爲 8 的節點,而後再進行判斷。指針
第一步在樹 A 中查找與根節點的值同樣的節點,這實際上就是樹的遍歷。能夠使用遞歸的方法進行遍歷。注意邊界條件的檢查,即檢查空指針。當樹 A 和樹 B 爲空時,應該給出相應的輸出。遞歸
第二步是判斷 A 中以 R 爲根節點的子樹是否是和樹 B 具備相同的結構。一樣能夠使用遞歸的思路來考慮:若是節點 R 的值和樹 B 的根節點相同,則以 R 爲根節點的子樹和樹 B 確定不具備相同的節點:若是它們的值相同,則遞歸地判斷它們各自的左右節點的值是否是相同。遞歸的終止條件是到達了樹 A 或者是樹 B的葉節點。io
//判斷樹 A 中是否含有子樹 B
#include<iostream>
using namespace std;test
typedef int ElemType;
typedef struct TNode
{
ElemType value;
struct TNode *LeftChild;
struct TNode *RightChild;
}TreeNode, *BinaryTree;stream
//建立一棵二叉查找樹
TreeNode* CreateBinaryTree(BinaryTree T, ElemType e)
{
if(T == NULL)
{
T = new TreeNode();
T->value = e;
T->LeftChild = NULL;
T->RightChild = NULL;
}
else
{
if(T->value > e)
T->LeftChild = CreateBinaryTree(T->LeftChild, e);
else if(T->value < e)
T->RightChild = CreateBinaryTree(T->RightChild, e);
}
return T; //返回根節點
}二叉樹
//建立一個普通的二叉樹
TreeNode* CreateTreeNode(ElemType e)
{
TreeNode *T = new TreeNode();
T->value = e;
T->LeftChild = NULL;
T->RightChild = NULL;
return T;
}
void ConnectTreeNode(TreeNode *pParent, TreeNode *pLeft, TreeNode *pRight)
{
if(pParent != NULL)
{
pParent->LeftChild = pLeft;
pParent->RightChild = pRight;
}
}遍歷
bool DoesTreeHaveSubTree(BinaryTree T1, BinaryTree T2)
{
if(T2 == NULL)
return true;
if(T1 == NULL)
return false;
if(T1->value != T2->value)
return false;
return DoesTreeHaveSubTree(T1->LeftChild, T2->LeftChild) &&
DoesTreeHaveSubTree(T1->RightChild, T2->RightChild);
}
bool HasSubTree(BinaryTree T1, BinaryTree T2)
{
bool result = false;
if(T1 != NULL && T2 != NULL)
{
if(T1->value == T2->value)
result = DoesTreeHaveSubTree(T1, T2);
if(!result)
result = HasSubTree(T1->LeftChild, T2);
if(!result)
result = HasSubTree(T1->RightChild, T2);
}
return result;
}
int main()
{
/*
test1: T1: 8 T2: 4
/ \ / \
4 9 3 6
/ \ \
3 6 10
/
2
*/
//TreeNode *T1 = NULL;
//TreeNode *T2 = NULL;
/*T1 = CreateBinaryTree(T1, 8);
T1 = CreateBinaryTree(T1, 4);
T1 = CreateBinaryTree(T1, 9);
T1 = CreateBinaryTree(T1, 10);
T1 = CreateBinaryTree(T1, 3);
T1 = CreateBinaryTree(T1, 6);
T1 = CreateBinaryTree(T1, 2);
T2 = CreateBinaryTree(T2, 4);
T2 = CreateBinaryTree(T2, 3);
T2 = CreateBinaryTree(T2, 6);
*/
/*
test2: T1: 8 T2: 8
/ \ / \
8 7 9 2
/ \
9 2
/ \
4 7
*/
TreeNode *T1Node1 = CreateTreeNode(8);
TreeNode *T1Node2 = CreateTreeNode(8);
TreeNode *T1Node3 = CreateTreeNode(7);
TreeNode *T1Node4 = CreateTreeNode(9);
TreeNode *T1Node5 = CreateTreeNode(2);
TreeNode *T1Node6 = CreateTreeNode(4);
TreeNode *T1Node7 = CreateTreeNode(7);
ConnectTreeNode(T1Node1, T1Node2, T1Node3);
ConnectTreeNode(T1Node2, T1Node4, T1Node5);
ConnectTreeNode(T1Node5, T1Node6, T1Node7);
TreeNode *T2Node1 = CreateTreeNode(8);
TreeNode *T2Node2 = CreateTreeNode(3);
TreeNode *T2Node3 = CreateTreeNode(2);
ConnectTreeNode(T2Node1, T2Node2, T2Node3);
bool result = HasSubTree(T1Node1, T2Node2);
cout << result << endl;
system("pause");
return 0;
}
測試用例:1)功能測試(樹 A 和 樹 B 都是普通的二叉樹,樹 B 是或者不是樹 A 的子結構)
2) 特殊輸入測試(兩棵二叉樹的一個或者兩個根節點爲 NULL指針,二叉樹的全部節點都沒有左子樹或右子樹)