【剑指offer】二叉树的下一个结点 --Java实现

二叉树的下一个结点

https://www.nowcoder.com/questionTerminal/9023a0c988684a53960365b889ceaf5e?answerType=1&f=discussion

【剑指offer】二叉树的下一个结点 --Java实现

1. 还原二叉树

1. 分析

既然给了二叉树的某个结点,且二叉树存储着指向父结点的指针(next),那我们可以先找到根节点,再对树进行中序遍历,最后根据中序遍历结果找到给定结点的下一结点

2. 代码

import java.util.*;
public class Solution {
    static ArrayList<TreeLinkNode> list = new ArrayList<>();
    public TreeLinkNode GetNext(TreeLinkNode pNode){
        TreeLinkNode par = pNode;
        while(par.next != null){
            par = par.next;
        }
        InOrder(par);
        for(int i=0;i<list.size();i++){
            if(pNode == list.get(i)){
                return i == list.size()-1?null:list.get(i+1);
            }
        }
        return null;
    }
    void InOrder(TreeLinkNode pNode){
        if(pNode!=null){
            InOrder(pNode.left);
            list.add(pNode);
            InOrder(pNode.right);
        }
    }
}

3. 复杂度

时间复杂度:
空间复杂度:

2. 直接找下一结点

1. 分析

以该二叉树为例,中序遍历为:{D,B,H,E,I,A,F,C,G}

仔细观察,可以把中序下一结点归为几种类型:

  1. 有右子树,下一结点是右子树中的最左结点,例如 B,下一结点是 H

  2. 无右子树,且结点是该结点父结点的左子树,则下一结点是该结点的父结点,例如 H,下一结点是 E

  3. 无右子树,且结点是该结点父结点的右子树,则我们一直沿着父结点追朔,直到找到某个结点是其父结点的左子树,如果存在这样的结点,那么这个结点的父结点就是我们要找的下一结点。例如 I,下一结点是 A;例如 G,并没有符合情况的结点,所以 G 没有下一结点

    2. 代码

    public class Solution {
    
    public TreeLinkNode GetNext(TreeLinkNode pNode) {
         // 1. 
         if (pNode.right != null) {
             TreeLinkNode pRight = pNode.right;
             while (pRight.left != null) {
                 pRight = pRight.left;
             }
             return pRight;
         }
         // 2. 
         if (pNode.next != null && pNode.next.left == pNode) {
             return pNode.next;
         }
         // 3. 
         if (pNode.next != null) {
             TreeLinkNode pNext = pNode.next;
             while (pNext.next != null && pNext.next.right == pNext) {
                 pNext = pNext.next;
             }
             return pNext.next;
         }
         return null;
     }
    }

    3. 复杂度:

    时间复杂度:
    空间复杂度:

全部评论
思路和大佬一样,只是那个在list里面判断不用那么复杂感觉,直接i<list.size()-1即可。 for(int i=0;i<list.size()-1;i++){ if(list.get(i)==node){ return list.get(i+1); } }
5 回复 分享
发布于 2020-04-02 15:20
第二中方法是什么鬼???直接pNode.next???
3 回复 分享
发布于 2019-10-13 19:00
方法二 while (pNext.next != null && pNext.next.right == pNext)是不是应该是left
2 回复 分享
发布于 2020-05-03 22:36
2-3合并: public class Solution { public TreeLinkNode GetNext(TreeLinkNode pNode) { if (pNode.right != null){ pNode = pNode.right; for(;pNode.left != null;pNode = pNode.left); } else{ TreeLinkNode fth = pNode.next; while (fth != null && fth.left != pNode){ pNode = fth; fth = pNode.next; } pNode = fth; } return pNode; } }
2 回复 分享
发布于 2020-01-01 23:38
有没有大佬说一下return i == list.size()-1?null:list.get(i+1);,这啥意思
1 回复 分享
发布于 2022-04-17 20:59
谢谢!第二种方法比官方题解讲的清楚多了
1 回复 分享
发布于 2020-07-11 11:29
第一种方法中的InOrder有什么作用啊?
1 回复 分享
发布于 2020-03-29 14:45
无右子树的两个分支其实可以合并,迭代两个节点pre即前一个结点和cur即前一个结点的父节点,初始时pre=输入,cur=输入的父节点,迭代停止条件为cur == nullptr || cur->left == pre。 总体代码: class Solution { public: TreeLinkNode* GetNext(TreeLinkNode* pNode) { if (pNode == nullptr) return nullptr; // 如果有右子 if (pNode->right) { TreeLinkNode* cur = pNode->right; while (cur->left) { cur = cur->left; } return cur; } // 无右子,一直迭代到cur为父的左子,此时父为下一个 else { TreeLinkNode* pre = pNode; TreeLinkNode* cur = pNode->next; while(cur != nullptr && cur->left != pre) { pre = cur; cur = cur->next; } return cur; } } };
1 回复 分享
发布于 2019-12-28 16:39
方法2看起来简单,但第三种情况属实有点难以理解。看了半天官方解答和答主的解答,才明白“直到找到某个结点是其父结点的左子树”的含义。
点赞 回复 分享
发布于 2023-03-20 01:02 四川
吹毛求疵一下,中序遍历方法中,在寻找根节点的时候,可以在while之前判断par是否为Null,万一pNode直接为null呢,直接访问pNode.next不妥。😉
点赞 回复 分享
发布于 2021-10-07 23:06
建议在第三种方法加一个判断嗷,当节点是整个树最右节点的话是取不到值的,下面是优化的代码: //3. 无右节点,并且为父节点的左节点 if (pNode.next != null) { temp = pNode.next; while (temp.next != null && temp.next.right == temp) { temp = temp.next; } if (temp.next != null && temp.next.left == temp) { return temp.next; } return null;
点赞 回复 分享
发布于 2020-12-08 21:36
秒啊
点赞 回复 分享
发布于 2020-07-19 19:23
楼主很棒,持续关注
点赞 回复 分享
发布于 2020-07-17 09:42
无右子树,且结点是该结点父结点的左子树,则下一结点是该结点的父结点,例如 H,下一结点是 E 2方法条件已经能够证明该结点下一节点为该结点的父结点 所以直接返回pNode.next
点赞 回复 分享
发布于 2019-10-15 09:31

相关推荐

就前几天旅游的时候,打开抖音就经常刷到这类视频:以前是高学历学生、老师、主持人,现在做着团播、擦边主播的工作,以及那些经过精心包装的“职业转型”故事——从铺天盖地的VLOG到所谓的“04年夜场工作日记”,这些内容在初中升学、高考放榜等关键时间节点持续发酵。可以说非常直接且精准地在潜移默化地影响着心智尚未成熟的青少年,使其对特殊行业逐渐脱敏。那我就想问了:某些传播公司、平台运营者甚至某些夜场的老板,你们究竟在传递怎样的价值观?点开那些视频,评论区里也是呈现明显的两极分化:一种是​​经济下行论​​:“现在就业市场已经艰难到这种程度了吗?”​​一种是事实反驳派​​:这些创作者往往拥有名校背景,从事着...
牛客刘北:被环境教育的,为了能拿到足够的钱养活自己,不甘心也得甘心,现在的短视频传播的思想的确很扭曲,但是很明显,互联网玩上一年你就能全款提A6,但你全心全意不吃不喝工作一年未必能提A6,但是在高考中考出现这个的确很扭曲,在向大家传播“不上学,玩互联网也可以轻松年入百万”,不是人变了,是社会在变
预测一下26届秋招形势
点赞 评论 收藏
分享
深夜书店vv:腾讯是这样的,去年很多走廊都加桌子当工区
点赞 评论 收藏
分享
评论
136
9
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务