【剑指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
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
方法二 while (pNext.next != null && pNext.next.right == pNext)是不是应该是left
2 回复 分享
发布于 2020-05-03 22:36
无右子树的两个分支其实可以合并,迭代两个节点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
第一种方法中的InOrder有什么作用啊?
1 回复 分享
发布于 2020-03-29 14:45
谢谢!第二种方法比官方题解讲的清楚多了
1 回复 分享
发布于 2020-07-11 11:29
有没有大佬说一下return i == list.size()-1?null:list.get(i+1);,这啥意思
1 回复 分享
发布于 2022-04-17 20:59
无右子树,且结点是该结点父结点的左子树,则下一结点是该结点的父结点,例如 H,下一结点是 E 2方法条件已经能够证明该结点下一节点为该结点的父结点 所以直接返回pNode.next
点赞 回复 分享
发布于 2019-10-15 09:31
楼主很棒,持续关注
点赞 回复 分享
发布于 2020-07-17 09:42
秒啊
点赞 回复 分享
发布于 2020-07-19 19:23
建议在第三种方法加一个判断嗷,当节点是整个树最右节点的话是取不到值的,下面是优化的代码: //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
吹毛求疵一下,中序遍历方法中,在寻找根节点的时候,可以在while之前判断par是否为Null,万一pNode直接为null呢,直接访问pNode.next不妥。😉
点赞 回复 分享
发布于 2021-10-07 23:06
方法2看起来简单,但第三种情况属实有点难以理解。看了半天官方解答和答主的解答,才明白“直到找到某个结点是其父结点的左子树”的含义。
点赞 回复 分享
发布于 2023-03-20 01:02 四川

相关推荐

喜欢吃蛋糕仰泳鲈鱼是我的神:字节可以找个hr 给你挂了,再放池子捞
点赞 评论 收藏
分享
尊尼获获:闺蜜在哪?
点赞 评论 收藏
分享
136 9 评论
分享
牛客网
牛客企业服务