inorder successor bst

==============================================
Successor with a parent pointer (iterative)

Idea: similar thinking process as above

  public Node(int val, Node left, Node right, Node parent){
    this.val = val;
    this.left = left;
    this.right = right;
    this.parent = parent;
  }
  
}

public Node successor(Node node){
  if(node == null) return null;
  
  if(node.right != null) return leftMost(node.right); // 
  
  Node cur = node;
  Node parent = node.parent;
  
  while(parent != null && parent.right == cur){
    cur = parent;
    parent = parent.parent;
  }
  return parent;
}

private Node leftMost(Node node){
  while(node.left != null){ //// node.left != null.  node != null from the above  if(node.right != null) return leftMost(node.right); 
    node = node.left;
  }
  return node;
}



===============================================
Successor without  a parent pointer (iterative)




// The idea is to compare root's value with p's value if root is not null, and consider the following two cases:
// root.val > p.val. In this case, root can be a possible answer, so we store the root node first and call it res. However, we don't know if there is anymore node on root's left that is larger than p.val. So we move root to its left and check again.
// root.val <= p.val. In this case, root cannot be p's inorder successor, neither can root's left child. So we only need to consider root's right child, thus we move root to its right and check again.
// We continuously move root until exhausted. To this point, we only need to return the res in case 1.'
    

public TreeNode successor(TreeNode root, TreeNode node){
  TreeNode result = null;
  while(root != null){
    if(root.val > node.val){
      result = root; /////
      root = root.left;
    }else{
      // root.val <= node.val
      root = root.right;
    }
  }
  return result;
}



===============================================
Successor without  a parent pointer (recursive )

上面那种方法也可以写成递归形式,写法也比较简洁,但是需要把思路理清,当根节点值小于等于p节点值,说明p的后继节点一定在右子树中,所以对右子节点递归调用此函数,如果根节点值大于p节点值,那么有可能根节点就是p的后继节点,或者左子树中的某个节点是p的后继节点,所以先对左子节点递归调用此函数,如果返回空,说明根节点是后继节点,返回即可,如果不为空,则将那个节点返回。这种解法可以用作模板,求BST的inorder successor和predecessor


public TreeNode successor(TreeNode root, TreeNode node){
  // base case
  if(root == null) return null;
  
  if(root.val > node.val){
    TreeNode result = successor(root.left, node);
    if(result == null){
      return root;
    }else{
      return result;
    }
    
    
  }else{
    return successor(root.right, node);
  }
}

 

Given a binary search tree and a node in it, find the in-order successor of that node in the BST.

Note: If the given node has no in-order successor in the tree, return null.

Example 1:

Input: root = [2,1,3], p = 1

 

  2

 / \

1   3

 

Output: 2

Example 2:

Input: root = [5,3,6,2,4,null,null,1], p = 6

 

      5

     / \

    3   6

   / \

  2   4

 /   

1

 

Output: null

 

 

                                           6 

           /        \

             2    8

                     /  \     /  \

        1    5       7    9 

         / \

        4      5.5

        /      /   \

       3      5.3    5.8 

         

         5.2 

 

   

 method 1 : 

Doesn't have a parent pointer , given a root node 

compare the root value with the node value 

 

two cases: 

if the root.value <= node.value

root = root.right

 

if root.value > node.val

root = root.left

result = root

 

example: find the inorder successor of 5

 

 

inorder successor of 5  means the smallest number bigger than node 5 

when root = 6 is bigger than node value, we move to the left of root, and update result as root value

because 1. root value is bigger than node.value, 2. if we don't find better result later, then 6 is the inorder successor of 5 

for example , in the bst graph below, 5's in order successor is 6, because 5 doesn't have right subtree . 

 

now we are at node 2 , 2 < 5 , so 2 is def not a result , so we don't update the result and we move to the right of 2, we are at 

5 , 5 = 5, so not an inorder successor. we move to the right of 5 , if 5 doesn't have right subtree , 5.right == null , now we are done, return result, which is 6/////////// (a)

 

if 5 has right subtree, we are now at 5.5 ,  5.5 is bigger than 5, we can update result with 5.5 , because when we are 6, since 6 is bigger than 5, so we moved left of 6

and elements at the left of 6 are all smaller than 6, so we can guarentee that 5.5 is smaller than 6, this is why we can just update the result, without comparing the value 

of 5.5 and 6, see which one is better, smaller . 

 

now we are at 5.3 , since 5.3 is bigger than 5 , so we update the result with 5.3 and move to the left of 5.3 , which is 5.2,

since 5.2 is bigger than 5 , so now we update the result with 5.2 , move to the left of 5.2 , which is null, so we are done, result is 5.2 /////////////(b)

 

case a and b all hit null at the end, so the stopping condition is when the root == null.

 

 

 

 

 

 

 

method 2:   

                                             

             7

                                            /

                                           6 

           /        \

             2    8

                     /  \     /  \

        1    5       7    9 

         /

        4

        /

       3

 

 

Has a parent pointer 

two cases: if the node has a right subtree, the inorder successor should be the leftmost node of the right subtree

2's inorder successor is 3 , left most node of 2.rigtht

 

 

if the node doesn't have a right subtree, two cases: 

 

if node.parent.left = node : the inorder successor is the parent 

4's inorder successor is 5 

 

 

if node.parent.right = node : go up along the parent, until we have node.parent.left = node.

5's inorder successor is 6 

 

so node is 5, parent is 2.       2.right = 5 , so move both parent and node up a level,  node = node.parent , parent = parent.parent

be careful here, if parent is null, we should be out of the while loop, 

now in this case, parent = 6, node = 2,   now we have parent.left = node. so we found the in order successor

 

posted on 2018-09-08 04:35  猪猪&#128055;  阅读(119)  评论(0)    收藏  举报

导航