448.二叉树查找树中序后继

描述

给一个二叉查找树(什么是二叉查找树),以及一个节点,求该节点的中序遍历后继,如果没有返回null

注意事项

It’s guaranteed p is one node in the given tree. (You can directly compare the memory address to find p)

样例

给出 tree = [2,1] node = 1:

      2
     /
   1

返回 node 2.
给出 tree = [2,1,3] node = 2:

      2
     / \
    1   3

返回 node 3.

挑战

O(h), where h is the height of the BST.

思路

从中序遍历的特性去寻找:左-根-右。中序遍历一个结点时,下一个结点有三种情况:

  1. 如果当前结点有右结点,则下一个遍历的是右子树的最左结点;
  2. 如果当前结点无右结点,若它是父节点的左儿子,则下一遍历的是父节点;
  3. 如果当前结点无右结点,且它是父节点的右儿子,则所在子树遍历完了。向上寻找一个作为左儿子的祖先结点,那么下一遍历的就是该祖先结点的父节点;(一直找到根节点为止)
  4. 如果上面三种情况都没找到,则该节点是树的最后一个结点,无后继结点

代码

public class Solution {
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        if (root == null) {
            return null;
        }

        // successor 记录用于记录中序遍历当前结点可能的后继结点
        // 后继结点是不是 successor 需要根据当前结点是否存在右子树来确定
        TreeNode successor = null;
        // root 代表当前结点
        // 不断查找,直到当前结点指向目标结点 p
        while (root != null && root != p) {
            // p 在当前结点的左子树
            // 只有往左查找时 successor 才需要不断更新
            if (root.val > p.val) {
                successor = root;
                root = root.left;
            // p 在某一结点的右子树
            // 向当前结点右子树查找时,successor 仍是当前结点的父结点不变
            } else {
                root = root.right;
            }
        }
        
        // while 循环结束后 root 指向点 p
        // 确定 p 的后继结点到底是 successor 还是其右子树的最左结点
        // 当前结点没有右子树
        if (root.right == null) {
            return successor;
        }
        
        // 当前结点存在右子树,一直找到右子树最左边结点
        root = root.right;
        while (root.left != null) {
            root = root.left;
        }
        return root;
    }
}
    原文作者:6默默Welsh
    原文地址: https://www.jianshu.com/p/0abb87cb11a2
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞