《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
算法一的主要思想是如果在遍历一颗二叉树时遇到空节点则在遍历序列中加入值"X",则两颗二叉树的结构相同以及每一个节点的值也相同和这两个二叉树的先序遍历结果相同互为充分必要条件(这里后序遍历也可以,但是中序遍历就不行)。这里的原因就是可以从之前的前序遍历结果(从前向后,第一个遍历值为从前二叉树的根节点)或后序遍历结果(从后向前,最后一个遍历值为从前二叉树的根节点)重新构建原来的二叉树。算法首先按照以上规则建立两颗二叉树的前序遍历序列然后检查一颗树的遍历序列是否为另一颗树的子序列来检验其是否为它的子树。
算法的时间复杂度为
O
(
n
+
m
)
O(n+m)
O(n+m),空间复杂度为
O
(
n
+
m
)
O(n+m)
O(n+m)(这里的空间主要是用来存贮遍历序列)。其中n和m分别为两颗树中节点的个数。算法实现代码如下:
class BinaryNode
{
private:
int data;
BinaryNode* left;
BinaryNode* right;
public:
BinaryNode(int value = 0, BinaryNode* pointer1 = nullptr, BinaryNode* pointer2 = nullptr)
{
data = value;
left = pointer1;
right = pointer2;
}
BinaryNode* getLeft()
{
return left;
}
BinaryNode* getRight()
{
return right;
}
int getData()
{
return data;
}
};
void getOrderString(BinaryNode * node,string &s)
{
if (node == nullptr)
{
s = s + "X ";
return;
}
s=s + to_string(node->getData())+" ";
getOrderString(node->getLeft(), s);
getOrderString(node->getRight(), s);
}
bool containTree(BinaryNode * t1, BinaryNode * t2)
{
string s1;
string s2;
getOrderString(t1, s1);
getOrderString(t2, s2);
return s1.find(s2)!= string::npos;
}
算法二的主要思想是依次遍历二叉树
T
1
T_1
T1中的每一个节点,当遇到节点和二叉树
T
2
T_2
T2的根节点的值相同时,从此节点开始比较从此节点开始的二叉树是否和二叉树
T
2
T_2
T2有相同的节点值以及结构,如果是则返回真否则继续向二叉树
T
1
T_1
T1的各个节点迭代。
算法二的最坏时间复杂度为
O
(
n
+
m
)
O(n+m)
O(n+m),空间复杂度为
O
(
l
o
g
2
(
n
)
+
l
o
g
2
(
m
)
)
O(log_2(n)+log_2(m))
O(log2(n)+log2(m))(这里的空间主要用于递归的函数栈)。其中n和m分别为两颗树中节点的个数。算法实现代码如下。
bool matchTree(BinaryNode* node1, BinaryNode* node2)
{
if (node1==nullptr&&node2==nullptr)
{
return true;
}
else if (node1 == nullptr || node2 == nullptr)
{
return false;
}
else if (node1->getData() != node2->getData())
{
return false;
}
else
{
return matchTree(node1->getLeft(), node2->getLeft()) && matchTree(node1->getRight(), node2->getRight());
}
}
bool subTree(BinaryNode* t1, BinaryNode* t2)
{
if (t1 == nullptr)
{
return false;
}
else if ((t1->getData() == t2->getData()) && matchTree(t1, t2))
{
return true;
}
return subTree(t1->getLeft(), t2) || subTree(t1->getRight(), t2);
}
bool containTree(BinaryNode * t1, BinaryNode * t2)
{
if (t2 == nullptr)
{
return true;
}
return subTree(t1, t2);
}