zoukankan      html  css  js  c++  java
  • 剑指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;
            
            
        }
    };
    
  • 相关阅读:
    第一篇:白话tornado源码之一个脚本引发的血案
    第二篇:白话tornado源码之待请求阶段
    Python 面向对象(初级篇)
    python 面向对象(进阶篇)
    Csharp启动exe文件
    UNIX时间戳
    JS日期格式化代码
    Android之什么是Activity和常用的ADB命令以及Android项目结构的认识
    thread同步测试
    Fluent NHibernate使用小结:(1)通用配置文件创建方法
  • 原文地址:https://www.cnblogs.com/sakurapiggy/p/13259449.html
Copyright © 2011-2022 走看看