Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Order Successor in Binary Search Tree

Given a node in a BST, how does one find the next higher key?

like image 842
shreyasva Avatar asked Mar 29 '11 11:03

shreyasva


People also ask

What is inorder successor in binary search tree?

In Binary Tree, Inorder successor of a node is the next node in Inorder traversal of the Binary Tree. Inorder Successor is NULL for the last node in Inorder traversal. In Binary Search Tree, Inorder Successor of an input node can also be defined as the node with the smallest key greater than the key of the input node.

What is inorder successor and predecessor in binary search tree?

When you do the inorder traversal of a binary tree, the neighbors of given node are called Predecessor(the node lies behind of given node) and Successor (the node lies ahead of given node).

How do you find the successor and predecessor in a binary search tree?

Where is the predecessor of a node in a tree, assuming all keys are distinct? If X has two children, its predecessor is the maximum value in its left subtree and its successor the minimum value in its right subtree. If it does not have a left child, a node's predecessor is its rst left ancestor.

How do you get the inorder successor?

We need to take care of 3 cases for any node to find its inorder successor as described below: Right child of node is not NULL. If the right child of the node is not NULL then the inorder successor of this node will be the leftmost node in it's right subtree. Right Child of the node is NULL.


3 Answers

The general way depends on whether you have a parent link in your nodes or not.

If you store the parent link

Then you pick:

  1. The leftmost child of the right child, if your current node has a right child. If the right child has no left child, the right child is your inorder successor.
  2. Navigate up the parent ancestor nodes, and when you find a parent whose left child is the node you're currently at, the parent is the inorder successor of your original node.

If you have right child, do this approach (case 1 above):

inorder-when-right-child

If you don't have a right child, do this approach (case 2 above):

inorder-when-no-right-child

If you don't store the parent link

Then you need to run a complete scan of the tree, keeping track of the nodes, usually with a stack, so that you have the information necessary to basically do the same as the first method that relied on the parent link.

like image 89
Lasse V. Karlsen Avatar answered Oct 05 '22 02:10

Lasse V. Karlsen


Python code to the Lasse's answer:

def findNext(node):
  # Case 1
  if node.right != None:
    node = node.right:
    while node.left:
      node = node.left
    return node

  # Case 2
  parent = node.parent
  while parent != None:
    if parent.left == node:
      break
    node = parent
    parent = node.parent
  return parent
like image 9
Vitalii Fedorenko Avatar answered Oct 05 '22 01:10

Vitalii Fedorenko


Here's an implementation without the need for parent links or intermediate structures (like a stack). This in-order successor function is a bit different to what most might be looking for since it operates on the key as opposed to the node. Also, it will find a successor of a key even if it is not present in the tree. Not too hard to change if you needed to, however.

public class Node<T extends Comparable<T>> {

private T data;
private Node<T> left;
private Node<T> right;

public Node(T data, Node<T> left, Node<T> right) {
    this.data = data;
    this.left = left;
    this.right = right;
}

/*
 * Returns the left-most node of the current node. If there is no left child, the current node is the left-most.
 */
private Node<T> getLeftMost() {
    Node<T> curr = this;
    while(curr.left != null) curr = curr.left;
    return curr;
}

/*
 * Returns the right-most node of the current node. If there is no right child, the current node is the right-most.
 */
private Node<T> getRightMost() {
    Node<T> curr = this;
    while(curr.right != null) curr = curr.right;
    return curr;
}

/**
 * Returns the in-order successor of the specified key.
 * @param key The key.
 * @return
 */
public T getSuccessor(T key) {
    Node<T> curr = this;
    T successor = null;
    while(curr != null) {
        // If this.data < key, search to the right.
        if(curr.data.compareTo(key) < 0 && curr.right != null) {
            curr = curr.right;
        }
        // If this.data > key, search to the left.
        else if(curr.data.compareTo(key) > 0) { 
            // If the right-most on the left side has bigger than the key, search left.
            if(curr.left != null && curr.left.getRightMost().data.compareTo(key) > 0) {
                curr = curr.left;
            }
            // If there's no left, or the right-most on the left branch is smaller than the key, we're at the successor.
            else {
                successor = curr.data;
                curr = null;
            }
        }
        // this.data == key...
        else {
            // so get the right-most data.
            if(curr.right != null) {
                successor = curr.right.getLeftMost().data;
            }
            // there is no successor.
            else {
                successor = null;
            }
            curr = null;
        }
    }
    return successor;
}

public static void main(String[] args) {
    Node<Integer> one, three, five, seven, two, six, four;
    one = new Node<Integer>(Integer.valueOf(1), null, null);
    three = new Node<Integer>(Integer.valueOf(3), null, null);
    five = new Node<Integer>(Integer.valueOf(5), null, null);
    seven = new Node<Integer>(Integer.valueOf(7), null, null);
    two = new Node<Integer>(Integer.valueOf(2), one, three);
    six = new Node<Integer>(Integer.valueOf(6), five, seven);
    four = new Node<Integer>(Integer.valueOf(4), two, six);
    Node<Integer> head = four;
    for(int i = 0; i <= 7; i++) {
        System.out.println(head.getSuccessor(i));
    }
}
}
like image 3
tandoc Avatar answered Oct 05 '22 03:10

tandoc