①相同的树
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入: 1 1 / \ / \ 2 3 2 3 [1,2,3], [1,2,3] 输出: true
示例 2:
输入: 1 1 / \ 2 2 [1,2], [1,null,2] 输出: false
示例 3:
输入: 1 1 / \ / \ 2 1 1 2 [1,2,1], [1,1,2] 输出: false
1.先将特殊情况判断完成,然后采用递归判断两棵树的根、左子节点、右子节点是否全部相等,如果相等则说明为相同的树,否则返回false:
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == NULL && q == NULL) //如果两棵树的根节点同时为空,则返回true
return true;
else if (p == NULL || q == NULL) //如果其中一个二叉树的根不为空而另一个二叉树的根为空的话返回false
return false;
else
{
if (p->val == q->val && isSameTree(p->left,q->left)
&& isSameTree(p->right,q->right)) //递归判断两个二叉树的左子节点与右子节点是否都相等,相等则返回true
return true;
else
return false;
}
}
};
2.非递归方法,二叉树的四种遍历方法(层序、先序、中序、后序)都有各自的迭代方法,这里先看前序的迭代写法,相当于同时遍历两个数,然后每个节点都进行比较:
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
stack<TreeNode*> s1, s2; //建立两个栈分别保存两个二叉树的节点信息
if (p) s1.push(p); //若p非空,将节点压入栈
if (q) s2.push(q); //若q非空,将节点压入栈
while (!s1.empty() && !s2.empty()) { //若两个二叉树未遍历完成,则继续迭代
TreeNode *t1 = s1.top(); s1.pop(); //创建指针保存栈顶元素,并将该元素弹出栈
TreeNode *t2 = s2.top(); s2.pop();
if (t1->val != t2->val) return false; //如果指针(节点)所指数据不相同,则返回false(两个树不同)
if (t1->left) s1.push(t1->left); //分别判断两个树的左子节点是否为空,不为空则压入栈
if (t2->left) s2.push(t2->left);
if (s1.size() != s2.size()) return false; //如此时栈元素数量不相同,则返回false
if (t1->right) s1.push(t1->right);//再分别判断两个树的右子节点是否为空,不为空则压入栈
if (t2->right) s2.push(t2->right);
if (s1.size() != s2.size()) return false;
}
return s1.size() == s2.size(); //遍历完成再次判断栈中数量是否相等,以防判空
}
};
②对称二叉树
扫描二维码关注公众号,回复:
3767709 查看本文章
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3]
是对称的。
1 / \ 2 2 / \ / \ 3 4 4 3
但是下面这个 [1,2,2,null,3,null,3]
则不是镜像对称的:
1 / \ 2 2 \ \ 3 3
说明:
如果你可以运用递归和迭代两种方法解决这个问题,会很加分。
1.递归方法,构造一个判断镜像的函数(传入两个参数,TreeNode* p、TreeNode* q),在该函数中递归判断是否为镜像的(对称),需要同时判断p的左子节点与q的右子节点、p的右子节点与q的左子节点是否同时相等,以此类推来比较完所有的节点:
class Solution {
public:
bool isJingxiang(TreeNode* p,TreeNode* q) //判断是否为镜像
{
if (p == NULL && q == NULL) //根节点同时为空,返回true
return true;
if (p == NULL || q == NULL) //根节点不同时为空,返回false
return false;
if (p->val != q->val) //根节点所指数据不同,返回false
return false;
return isJingxiang(p->left,q->right) && isJingxiang(p->right,q->left); //递归判断
}
bool isSymmetric(TreeNode* root) {
if (root == NULL)
return true;
return isJingxiang(root->left,root->right); //调用镜像判断函数进行对称树的判断
}
};
2.迭代方法,使用队列存储二叉树的节点信息,利用队列的先进先出特点进行迭代,可以得出判断:
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if (!root) return true; //如果根节点为空,则为镜像,返回true
queue<TreeNode*> q1,q2; //使用队列保存节点
q1.push(root->left); //先将左节点与右节点分别存入两个队列
q2.push(root->right);
while (!q1.empty() && !q2.empty())
{
TreeNode* node1 = q1.front(); //指针node1指向的是左节点
TreeNode* node2 = q2.front(); //指针node2指向的是右节点
q1.pop(); //将两个数据从队列中弹出
q2.pop();
if (node1 && !node2 || !node1 && node2) return false; //如果两个节点中有一个为空,则返回false
if (node1) //节点不为空
{
if (node1->val != node2->val) //两者指向的数据不相同,返回false
return false;
q1.push(node1->left); //将左节点的左子节点与右子节点存入队列q1
q1.push(node1->right);
q2.push(node2->right); //将右节点的左子节点与右子节点存入队列q2
q2.push(node2->left);
//再迭代判断时,根据队列先进先出的特点,接下来比较的是左节点的左子节点与右节点的右子节点,这样就能完成迭代判断
}
}
return true; //在经过上述迭代判断之后,如果未返回值,说明该二叉树为对称树
}
};