1. 程式人生 > >Symmetric Tree(對稱樹)

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;
}

以上。