Symmetric Tree(對稱樹)
題目描述
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree is symmetric:
But the following is not:
Note:
Bonus points if you could solve it both recursively and iteratively.
confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.
OJ’s Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where ‘#’ signifies a path terminator where no node exists below.
Here’s an example:
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".
題目大意
判斷一棵樹是否是對稱樹。
要注意,對稱樹是一棵樹的左右子樹互為鏡面;
所以是左子樹的左孩子==右子樹的右孩子。
這點要區別於相等樹。
相等二叉樹:左子樹的左孩子==右子樹的左孩子
思路
可以用遞迴也可以把遞迴改成非遞迴(所有的遞迴都可以改寫成非遞迴的形式)。
不管遞迴還是非遞迴,判斷條件都是一樣的,
(1)首先判斷當前結點是否為NULL,如果都為NULL,顯然是相等的,
(2)如果不是兩棵樹的當前結點都為NULL,其中有一個為NULL,那麼兩棵樹必不相等,
(3)如果兩棵樹的兩個結點的值不相等,那麼兩棵樹必不相等。條件判斷完後,說明當前結點相等且不為NULL。接下來就再判斷當前結點的左右子樹,在遞迴方法中,用遞迴手段去判斷;在非遞迴方法中,將當前結點的左右孩子結點入隊,在去迴圈判斷。由此可見,遞迴、非遞迴,思想是一樣的。
但是在入隊的時候要注意,因為是判斷是否是映象樹,所以一棵樹以左右孩子子樹的順序入隊,另一棵樹要以右左孩子的順序入隊。
程式碼
遞迴
#include<iostream>
#include<queue>
using namespace std;
// Definition for binary tree
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
bool isSymmetric(TreeNode *root)
{
if(root == NULL)return true;
return help_fun(root->left, root->right);
}
bool help_fun(TreeNode *root1, TreeNode *root2)
{
if(root1==NULL && root2==NULL)return true;
else if(root1==NULL || root2==NULL)return false;
else if(root1->val != root2->val)return false;
// 注意:第一棵樹的左孩子與第二顆樹的右孩子比較
// 第二顆樹的右孩子與第一棵樹的左孩子相比較
return help_fun(root1->left, root2->right) && help_fun(root1->right, root2->left);
}
int main()
{
return 0;
}
非遞迴
#include<iostream>
#include<queue>
using namespace std;
// Definition for binary tree
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
typedef TreeNode* tree;
bool isSymmetric(TreeNode *root)
{
if(root == NULL)return true;
queue<tree> q1, q2;
// 把根結點的左右子樹分別看成一棵樹,判斷這兩棵樹是否對稱
q1.push(root->left);
q2.push(root->right);
while(!q1.empty() && !q2.empty())
{
tree tmp1 = q1.front();
tree tmp2 = q2.front();
// 記得出隊
q1.pop(); q2.pop();
// 當前結點都為NULL,就繼續去比較隊內其他結點
if(tmp1==NULL && tmp2==NULL)continue;
// 只有一個結點為NULL,另一個結點非NULL,必不對稱
else if(tmp1==NULL || tmp2==NULL)return false;
// 結點值不相等,必不對稱
else if(tmp1->val != tmp2->val)return false;
// 前面三個判斷條件都沒有走,說明tmp1和tmp2都非NULL
// 就把他們的左右孩子入隊
// 注意:第一個入隊順序為:1. 左 2. 右
q1.push(tmp1->left);
q1.push(tmp1->right);
// 注意:第二個入隊順序為:1. 右 2. 左
q2.push(tmp2->right);
q2.push(tmp2->left);
}
// 兩個佇列有一個非NULL,說明必不對稱
if(!q1.empty() || !q2.empty())return false;
return true;
}
int main()
{
return 0;
}
以上。