1. 程式人生 > >判斷一棵樹為另一顆樹的子樹

判斷一棵樹為另一顆樹的子樹

題目:

    有兩顆二叉樹,判斷其中一顆A是否是另一顆B的子樹。


解決思想:

    按先序遍歷樹B的每個結點,判斷結點是否和樹A的根結點相同。若相同,再判斷以該結點為根結點的樹是否有和樹A相同的子樹。


程式碼:

#include <iostream>
using namespace std;

struct BTree
{
	int m_val;
	BTree *m_lchild;
	BTree *m_rchild;
};

bool DoesTree1HaveTree2(BTree *root1, BTree *root2);


//相當於以前序遍歷判斷每個結點是否和子樹的根結點相同
bool HasSubTree(BTree *root1, BTree *root2)
{
	if (root1 == NULL || root2 == NULL)
		return false;

	bool result = false;
	if (root1->m_val == root2->m_val)    //找到一個結點與目標子樹根結點相同
		result = DoesTree1HaveTree2(root1, root2);    //判斷以該結點為根結點是否有棵子樹與目標子樹相同
	if (!result)    //上個結點與子樹根結點不同
		result = HasSubTree(root1->m_lchild, root2);    //判斷左子結點
	if (!result)    //左子結點也與子樹根結點不同
		result = HasSubTree(root1->m_rchild, root2);    //判斷右子結點

	return result;
}

bool DoesTree1HaveTree2(BTree *root1, BTree *root2)
{
	if (root2 == NULL)    //能走到這步,說明該結點前面的結點都相同
		return true;
	if (root1 == NULL)    //即root2!=NULL,root1=NULL
		return false;
	if (root1->m_val != root2->m_val)
		return false;

	return DoesTree1HaveTree2(root1->m_lchild, root2->m_lchild) && DoesTree1HaveTree2(root1->m_rchild, root2->m_rchild);
}

/* 構造一顆二叉樹 */
void CreateBTree(BTree **T)
{
	int val;
	cin >> val;
	if (val == 0)    //輸入0表示結尾
		*T = NULL;
	else
	{
		*T = new BTree;
		if (*T == NULL)
			return ;
		(*T)->m_val = val;
		CreateBTree(&(*T)->m_lchild);
		CreateBTree(&(*T)->m_rchild);
	}
}

int main()
{
	printf("輸入樹1的結點:\n");
	BTree *T1;
	CreateBTree(&T1);
	printf("輸入樹2的結點:\n");
	BTree *T2;
	CreateBTree(&T2);
	cout << "樹2是1的子樹?(1:是;0:否):" << HasSubTree(T1, T2) << endl;
	return 0;
}


測試:

1.T1:123000246000500 T2:2400500 結果:1

2.T1:123000246000500 T2:2300500 結果:0