1. 程式人生 > >劍指offer——樹的子結構(26題)

劍指offer——樹的子結構(26題)

題目:輸入兩棵二叉樹A和B,判斷B是不是A的子結構。

老生常談,有關二叉樹的題型解答,離不開遍歷演算法,此題又可以看成是用中序遍歷改進法來解答。

其思路如下:

i、先從A樹的根節點開始,一一與B樹的節點對應匹配比較;

ii、如i不成功,則遍歷根的左兒子,重複i過程;

iii、如ii不成功,則遍歷根的右兒子,重複i過程。

程式碼實現如下:

#include<iostream>
#include<cmath>

using namespace std;

struct TreeNode {
	double val;
	TreeNode* left, *right;
	TreeNode(double x):val(x),left(nullptr),right(nullptr){}
};

bool equal(TreeNode* root1, TreeNode* root2) {
	if (fabs(root1->val - root2->val) < 0.000001)
		return true;
	return false;
}

bool doesTree1HaveTree2(TreeNode* root1, TreeNode* root2) {
	if (root2 == nullptr)//能到達B樹的葉子節點的子節點,則返回true
		return true;
	if (root1 == nullptr)//能到達A樹的葉子節點的子節點,說明還不能匹配成功,返回false
		return false;
	if (!equal(root1, root2))//兩節點值不相等,也返回false
		return false;

	return doesTree1HaveTree2(root1->left, root2->left) && doesTree1HaveTree2(root1->right, root2->right);
}

bool hasSubtree(TreeNode* root1, TreeNode* root2) {
	if (!root1 || !root2)
		return false;
	int result = false;
	if (equal(root1, root2))//從根節點判斷,是否與root2匹配
		result = doesTree1HaveTree2(root1, root2);
	if (!result)//在根節點開始,與root2匹配不成功下,遞迴判斷左兒子與root2是否匹配
		result = hasSubtree(root1->left, root2);
	if (!result)//在根節點且根的左子樹,與root2匹配不成功下,遞迴判斷右兒子與root2是否匹配
		result = hasSubtree(root1->right, root2);
	return result;
}