剑指OFFER_二叉树的下一个节点

剑指OFFER_二叉树的下一个节点

题目描述

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

思路

拿到这道题一开始我的思路是写一个中序遍历,带入这个节点,返回下一个节点即可;

不过越做发现问题越多,因为很难对中序遍历进行魔改,更何况给定的节点有可能需要返回上一个节点;

无奈之下去看了题解,发现题解真有意思:

题解给出了两种思路,一种是在笔试的情况下,一种是在面试的情况下:

笔试的情况下,只要能得到答案就好,因此首先从当前节点回溯至根节点,再进行中序遍历,得到结果;

这个办法确实简单粗暴,不过效率不高,适合笔试;

面试的话需要设计时间复杂度低的算法,题解对所有的情况进行了分类讨论:

  1. 当前节点有右子树,那么下一个节点就是右子树的最左节点,如果不存在就是右子树自身;
  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)
    {
        TreeLinkNode* node = pNode;
        if (!node) return nullptr;
        // 有右子树的情况
        if (node->right) {
            node = node->right;
            while (node->left) {
                node = node->left;
            }
            return node;
        }
        // 当前无右子树的情况
        while (node->next) {
            if (node == node->next->left) {
                return node->next;
            }
            node = node->next;
        }
        
        // 为最后一个节点
        return nullptr;
        
        
    }
};
posted @ 2020-07-07 10:44  樱花小猪  阅读(103)  评论(0编辑  收藏  举报