逻辑分析:
1. 想要知道该二叉树是否为对称二叉树,首先需要知道的一点是,以根结点为分界线,左右孩子“对折”,是否能“重合”
2. 判断是否为对称二叉树,我们只需要处理根节点的左右子树即可。那么想象一下,第一步,我们是否只需要把左子树的左孩子和右子树的右孩子进行比较就可以了呢?答案是不完全正确,这只能说明左子树的外侧和右子树的外侧是对称的,不能代表内侧也对称
3. 与右子树的所有右孩子对比左子树的所有左孩子结束后,我们还需要对比左子树的右孩子和右子树的左孩子,也就是左子树的内侧所有结点和右子树的所有左侧结点对比;我们可以在大脑中抽象出来对比的哪些结点(如下图所示)。
算法思想:
根据上述逻辑分析,不难推断出,用递归的方式是最方便的
1. 首先要进行排除左右子树有一个是空的情况,一个为空,一个不为空,那么说明肯定是不对称的,直接返回false,再者就是两边子树的结点值不相等的情况也直接返回false
2. 其次如果根结点的左右指针都指向null,那么可以说明这课树只有一个根结点,显然是对称的,返回true。
3. 排除上述的几种情况,还剩下一种情况是什么?很显然就是两个结点的值相等,并且二者都不为空,那么就可以断定,这棵树一定就是对称二叉树了。
4. 那么根结点的左右子树结点对比完了,如果是相等的,那么还需要进行下一次上述的重复操作。只需要一个对比外侧的递归函数和对比内侧的递归函数即可,函数的每一次执行,都会执行上述第一步,第二步,第三步的操作。由此就可以判断出,该二叉树是否为对称二叉树。
代码实现:
//对称二叉树(是对称二叉树返回true,否则false)递归法
bool symmetryTree(TreeNode* root){
if(root == nullptr) return false;
return compareSymmetryTree(root->lchild,root->rchild);
}
static bool compareSymmetryTree(TreeNode* left,TreeNode* right){
//先排除空节点的情况
if(left == nullptr && right != nullptr) return false;
if(left != nullptr && right == nullptr) return false;
if(left == nullptr && right == nullptr) return true;
//再排除数值不同的情况
if(left->data != right->data) return false;
//比较树的两侧节点数值是否相同
bool besideChildBranch = compareSymmetryTree(left->lchild,right->rchild);
//比较树的内两侧节点数值是否相同
bool innerChildBranch = compareSymmetryTree(left->rchild,right->lchild);
return besideChildBranch && innerChildBranch;
}
相同的树leetcode-100
算法思想
与对称二叉树算法思想类似,只不过对称二叉树是外侧和内侧分别对比,而相同树是对比外侧和外侧,内侧和内侧,这样才可以判断出两棵树是否相同
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
return handlerTheSameTree(p,q);
}
bool handlerTheSameTree(TreeNode* left,TreeNode* right){
if(left == nullptr && right == nullptr) return true;
if(left == nullptr || right == nullptr) return false;
if(left->val != right->val) return false;
return handlerTheSameTree(left->left,right->left) && handlerTheSameTree(left->right,right->right);
}
};