对称的二叉树 + 二叉树的下一个结点

1、对称二叉树

1.1 题目:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
1.2 原理:需要注意的是,题目中同样的理解,必须是结构一样,且对应节点的值也要是一样的。遍历的思想,对于根节点的左右子树可以分别将其看成两个二叉树1和树2,同时遍历两个二叉树,只要对应的值相当,每次遍历中比较树1的左节点与树2的右节点,树1的右节点和树2的左节点,核心在这里,保证对称关系
1.3 代码:

// 遍历二叉树
bool pre(TreeNode* p1, TreeNode* p2)
{
    if(p1&&p2)
    {
        if(p1->val==p2->val)
            return pre(p1->left, p2->right)&&pre(p1->right, p2->left);
        else
            return false;
    }
    else
    {
        // p1和p2都是NULL
        if(p1==p2)
            return true;
        else
            return false;
    }
}

class Solution {
public:
    bool isSymmetrical(TreeNode* pRoot)
    {
        if(pRoot==NULL)
            return true;
        TreeNode* pL = pRoot->left;
        TreeNode* pR = pRoot->right;
        return pre(pL, pR);
    }

};

1.4 总结:

(1)在意这种双二叉树同时遍历的这种做法,本质上和普通的二叉树的遍历是没有区别的,只不过每次的访问节点,同时访问了另个节点。
(2)镜像二叉树和原二叉树的区别和联系。主要是对称的。

2、二叉树的下一个结点

2.1 题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
2.2 原理:由于是中序遍历,所以不要管左子树了,因为访问到当前的结点的时候,其左子树如果存在一定已经被访问过了。因此可以分为以下几张情况:
(1)当前节点的右子树存在:直接返回其右子树的最左的节点指针即可。
(2)当前节点的右子树不存在:这种情况较为复杂,再分为两种情况讨论。

1、当前节点是其父节点的左子树,那么下一个要访问的就是其父节点
2、当前节点是其父节点的右子树,这种情况最复杂,需要继续回溯其父节点,只到找到其是父节点的左子树为止。

2.3 代码:

struct TreeLinkNode {
    int val;
    struct TreeLinkNode *left;
    struct TreeLinkNode *right;
    struct TreeLinkNode *next;
    TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {

    }
};

class Solution {
public:
    TreeLinkNode* GetNext(TreeLinkNode* pNode)
    {
        if(pNode==NULL)
            return NULL;

        //当前节点的右子树不存在
        if(pNode->right==NULL)
        {
            if(pNode->next==NULL)
                return NULL;
            else
            {
                //当前节点是左子树
                if(pNode->next->left==pNode)
                    return pNode->next;
                else  //右子树
                {
                    TreeLinkNode *p = pNode;
                    while((p->next)&&(p->next->right==p))
                        p=p->next;
                    return p->next;
                }

            }
        }

        //当前节点的右子树存在
        else
        {
            //找到右子树的最左节点返回
            TreeLinkNode *p = pNode->right;
            while(p->left)
                p = p->left;
            return p;
        }
        return NULL;
    }
};

2.4 总结和注意:

1、这种复杂且多样情况的二叉树的问题,一定注意沉下心来,一点点分析,吧各种可能出现的情况想清楚以及对应的解决思路,先自己的在草稿纸上画一画,想清楚,切记不动笔直接空想,多种情况按顺序进行区别。
2、涉及到二叉树的问题,一定注意判断指针的存在性,只有指针存在了,才能对其节点进行操作,这是关键中的关键,编程上的注意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值