0

My project wants me to print out the predecessor and the successor of a binary search tree. The assignment requires me to pass in the data of a node as an argument. When I try to print out the predecessor of a given node's data, it gives me 0. I try tirelessly how to solve the problem and found no where. Hope you can find where the problem lies.

Here is the method:

  public void findPredecessor(Node root, int data)
  {
    int predecessor = 0;
    if(root != null)
    {
        if(root.data == data)
        {
            if(root.left != null)
            {
                Node n = root.left;
                while(n.right != null) n = n.right;
                predecessor=  n.data;
            }
        }
        else if(root.data < data)
        {
            predecessor = root.data;
            findPredecessor(root.left, data);
        }
    }
    System.out.print(predecessor);
}

public void printPredecessor(int data)
{
    findPredecessor(root, data);
}
H.Ding
  • 21
  • 2
  • 4
  • 1
    Shouldn't something happen if `root.data > data`? Your code just gives up. – ajb Aug 29 '17 at 04:13
  • Possible duplicate of [In Order Successor in Binary Search Tree](https://stackoverflow.com/questions/5471731/in-order-successor-in-binary-search-tree) – Bernhard Barker Dec 31 '17 at 16:54

2 Answers2

0

Here's the pseudo-code for the right approach as i think of it:

Input: root node,key | output: predecessor node, successor node 
  • If root is NULL then return

  • if key is found then

    a. If its left subtree is not null Then predecessor will be the right
       most child of left subtree or left child itself i.e maximum value
       in left subtree 
    
    b. If its right subtree is not null Then successor will be the lefmost 
       child of right subtree or right child itself i.e minimum value in 
       right subtree.
    

    return

  • If key is smaller then root node set the successor as root
    and search recursively into left subtree

    else set the predecessor as root and search recursively into right subtree

Edit: If successor or predecessor returns null print null.

Example

                         (1)<--root
                            \
                              \
                               (3)
                               /
                              /
                           (2)<--targetKey
Initially,
 successor=null
 predecessor=null

 FunctionCall(root,successor,predecessor,targetKey):

         Here root's key is smaller than target key so,
         Set predecessor=root.

                          (1)   <--predecessor
                            \
                              \
                               (3)
                               /
                              /
                           (2)<--targetKey


         //Search recursively in right subtree
     FunctionCall(root.right,successor,predecessor,targetKey):

              Here root's key is greater than target key so,
         Set successor=root.
                          (1) <--predecessor
                            \
                              \
                               (3) <--successor
                               /
                              /
                           (2)<--targetKey

           //Search recursively in left subtree
     FunctionCall(root.left,successor,predecessor,targetKey):

               Root.key==targetKey
                 Also,
                Root.right==null
                Root.left==null
            Return

  Successor=3
  Predecessor=1

Hope it helps!

  • What if the key is found and the left subtree is null? You've left that case out. – ajb Aug 29 '17 at 04:15
  • But how do you find the predecessor? (P.S. If you're responding to a larger version of my comment that I edited after I posted it, sorry--that was my fault.) – ajb Aug 29 '17 at 04:18
  • Also we can perform a check if successor or predecessor returned is null or not. – Akash_Triv3di Aug 29 '17 at 04:23
  • This will work if the root of the entire tree equals the key. But not when you're going down recursively. Try this: You have three nodes, 1, 3, 2. The right link of node 1 points to node 3. The left link of node 3 points to node 2. Find the predecessor of 2. Your algorithm won't work. It's possible that it will work and you just wrote it badly. If that's the case, please work on filling in the missing details. – ajb Aug 29 '17 at 04:41
  • I think you are not getting the code ,which in your case will execute third part where key is smaller or greater than the root's key.Answer in your case will be prede:1,successor:3. – Akash_Triv3di Aug 29 '17 at 04:51
  • I guess your explanation helps somewhat, but it's pretty confusing about what you're doing with `predecessor` and `successor`. You say they're the output of the method, but are they the output of the recursive call, or just the initial call? You've shown a `FunctionCall` that takes `pred` and `succ` as parameters. Are those the same as `predecessor` and `successor`, or are they different variables? If you're passing them in, are you expecting that the function call will set them? (Which doesn't work in Java since it's pass-by-value.) – ajb Aug 30 '17 at 03:46
  • Anyway, I think that what you're thinking of doing will work, but I felt like I had to do some mind-reading to figure out what you were thinking. – ajb Aug 30 '17 at 03:51
  • They are same as successor and predecessor which were null initially and then passed in the method.Know that i am not posting the code and want OP to do it oneself. In java we can make them static and then don't have to pass.Well in c++ we can pass. – Akash_Triv3di Aug 30 '17 at 04:43
0

You can find the predecessor and successor of a node in a binary search tree by using an inOrder traversal. The basic structure of an inOrder traversal is:

inOrder(Node n)
  if (n == null) return;
  inOrder(n.left)
  visit(n)
  inOrder(n.right)

In this case, when we visit a node we want to keep track of the predecessor, matched node, and successor, based on which we've already seen. Here's the basic logic:

visit(n)
  if n.val == searchVal
    match = n
  else if match == null
    predecessor = n
  else if successor == null
    successor = n;

Here's some Java code. I'm using a simple 3 element array to store the predecessor, match, and successor.

class Node
{
  int val;
  Node left, right;
}

static void inOrder(Node n, int val, Node[] seq)
{
  if(n == null) return;

  inOrder(n.left, val, seq);

  if(n.val == val) 
    seq[1] = n;
  else if(seq[1] == null)
    seq[0] = n;
  else if(seq[2] == null)
    seq[2] = n;

  inOrder(n.right, val, seq);   
}

public static void main(String[] args)
{
  Node root = buildTree();
  int searchVal = Integer.parseInt(args[0]);

  Node[] seq = new Node[3];
  inOrder(root, searchVal , seq);
  System.out.println("Predecessor: " + seq[0]);
  System.out.println("Match: " + seq[1]);
  System.out.println("Successor: " + seq[2]);
}
RaffleBuffle
  • 5,396
  • 1
  • 9
  • 16