樹的子結構

題目:輸入兩棵二叉樹 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指針,二叉樹的全部節點都沒有左子樹或右子樹)

相關文章
相關標籤/搜索