In Order Successor in Binary Search Tree - algorithm

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

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:
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.
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):
If you don't have a right child, do this approach (case 2 above):
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.

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

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));
}
}
}

Check out here : InOrder Successor in a 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
Inoorder 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 input node.

With Binary Search Tree, the algorithm to find the next highest node of a given node is basically finding the lowest node of the right sub-tree of that node.
The algorithm can just be simply:
Start with the right child of the given node (make it the temporary current node)
If the current node has no left child, it is the next highest node.
If the current node has a left child, make it the current node.
Repeat 2 and 3 until we find next highest node.

we dont need parent link or stack to find the in order successor in O(log n) (assuming balanced tree).
Keep a temporary variable with the most recent value encountered in the inorder traversal that is larger than the key. if inorder traversal finds that the node does not have a right child, then this would be the inorder successor. else, the leftmost descendant of the right child.

C++ solution assuming Nodes have left, right, and parent pointers:
This illustrates the function Node* getNextNodeInOrder(Node) which returns the next key of the binary search tree in-order.
#include <cstdlib>
#include <iostream>
using namespace std;
struct Node{
int data;
Node *parent;
Node *left, *right;
};
Node *createNode(int data){
Node *node = new Node();
node->data = data;
node->left = node->right = NULL;
return node;
}
Node* getFirstRightParent(Node *node){
if (node->parent == NULL)
return NULL;
while (node->parent != NULL && node->parent->left != node){
node = node->parent;
}
return node->parent;
}
Node* getLeftMostRightChild(Node *node){
node = node->right;
while (node->left != NULL){
node = node->left;
}
return node;
}
Node *getNextNodeInOrder(Node *node){
//if you pass in the last Node this will return NULL
if (node->right != NULL)
return getLeftMostRightChild(node);
else
return getFirstRightParent(node);
}
void inOrderPrint(Node *root)
{
if (root->left != NULL) inOrderPrint(root->left);
cout << root->data << " ";
if (root->right != NULL) inOrderPrint(root->right);
}
int main(int argc, char** argv) {
//Purpose of this program is to demonstrate the function getNextNodeInOrder
//of a binary tree in-order. Below the tree is listed with the order
//of the items in-order. 1 is the beginning, 11 is the end. If you
//pass in the node 4, getNextNode returns the node for 5, the next in the
//sequence.
//test tree:
//
// 4
// / \
// 2 11
// / \ /
// 1 3 10
// /
// 5
// \
// 6
// \
// 8
// / \
// 7 9
Node *root = createNode(4);
root->parent = NULL;
root->left = createNode(2);
root->left->parent = root;
root->right = createNode(11);
root->right->parent = root;
root->left->left = createNode(1);
root->left->left->parent = root->left;
root->right->left = createNode(10);
root->right->left->parent = root->right;
root->left->right = createNode(3);
root->left->right->parent = root->left;
root->right->left->left = createNode(5);
root->right->left->left->parent = root->right->left;
root->right->left->left->right = createNode(6);
root->right->left->left->right->parent = root->right->left->left;
root->right->left->left->right->right = createNode(8);
root->right->left->left->right->right->parent =
root->right->left->left->right;
root->right->left->left->right->right->left = createNode(7);
root->right->left->left->right->right->left->parent =
root->right->left->left->right->right;
root->right->left->left->right->right->right = createNode(9);
root->right->left->left->right->right->right->parent =
root->right->left->left->right->right;
inOrderPrint(root);
//UNIT TESTING FOLLOWS
cout << endl << "unit tests: " << endl;
if (getNextNodeInOrder(root)->data != 5)
cout << "failed01" << endl;
else
cout << "passed01" << endl;
if (getNextNodeInOrder(root->right) != NULL)
cout << "failed02" << endl;
else
cout << "passed02" << endl;
if (getNextNodeInOrder(root->right->left)->data != 11)
cout << "failed03" << endl;
else
cout << "passed03" << endl;
if (getNextNodeInOrder(root->left)->data != 3)
cout << "failed04" << endl;
else
cout << "passed04" << endl;
if (getNextNodeInOrder(root->left->left)->data != 2)
cout << "failed05" << endl;
else
cout << "passed05" << endl;
if (getNextNodeInOrder(root->left->right)->data != 4)
cout << "failed06" << endl;
else
cout << "passed06" << endl;
if (getNextNodeInOrder(root->right->left->left)->data != 6)
cout << "failed07" << endl;
else
cout << "passed07" << endl;
if (getNextNodeInOrder(root->right->left->left->right)->data != 7)
cout << "failed08 it came up with: " <<
getNextNodeInOrder(root->right->left->left->right)->data << endl;
else
cout << "passed08" << endl;
if (getNextNodeInOrder(root->right->left->left->right->right)->data != 9)
cout << "failed09 it came up with: "
<< getNextNodeInOrder(root->right->left->left->right->right)->data
<< endl;
else
cout << "passed09" << endl;
return 0;
}
Which prints:
1 2 3 4 5 6 7 8 9 10 11
unit tests:
passed01
passed02
passed03
passed04
passed05
passed06
passed07
passed08
passed09

You can read additional info here(Rus lung)
Node next(Node x)
if x.right != null
return minimum(x.right)
y = x.parent
while y != null and x == y.right
x = y
y = y.parent
return y
Node prev(Node x)
if x.left != null
return maximum(x.left)
y = x.parent
while y != null and x == y.left
x = y
y = y.parent
return y

If we perform a in order traversal then we visit the left subtree, then root node and finally the right subtree for each node in the tree.
Performing a in order traversal will give us the keys of a binary search tree in ascending order, so when we refer to retrieving the in order successor of a node belonging to a binary search tree we mean what would be the next node in the sequence from the given node.
Lets say we have a node R and we want its in order successor we would have the following cases.
[1] The root R has a right node, so all we need to do is to traverse to the left most node of R->right.
[2] The root R has no right node, in this case we traverse back up the tree following the parent links until the node R is a left child of its parent, when this occurs we have the parent node P as the in order successor.
[3] We are at the extreme right node of the tree, in this case there is no in order successor.
The implementation is based on the following node definition
class node
{
private:
node* left;
node* right;
node* parent
int data;
public:
//public interface not shown, these are just setters and getters
.......
};
//go up the tree until we have our root node a left child of its parent
node* getParent(node* root)
{
if(root->parent == NULL)
return NULL;
if(root->parent->left == root)
return root->parent;
else
return getParent(root->parent);
}
node* getLeftMostNode(node* root)
{
if(root == NULL)
return NULL;
node* left = getLeftMostNode(root->left);
if(left)
return left;
return root;
}
//return the in order successor if there is one.
//parameters - root, the node whose in order successor we are 'searching' for
node* getInOrderSucc(node* root)
{
//no tree, therefore no successor
if(root == NULL)
return NULL;
//if we have a right tree, get its left most node
if(root->right)
return getLeftMostNode(root->right);
else
//bubble up so the root node becomes the left child of its
//parent, the parent will be the inorder successor.
return getParent(root);
}

We can find the successor in O(log n) without using parent pointers (for a balanced tree).
The idea is very similar to when you have parent pointers.
We can define a recursive function that achieves this as follows:
If the current node is the target, return the left-most / smallest node of its right subtree, if it exists.
Recurse left if the target is smaller than the current node, and right if it's greater.
If the target is to the left and we haven't found a successor yet, return the current node.
Pseudo-code:
Key successor(Node current, Key target):
if current == null
return null
if target == current.key
if current.right != null
return leftMost(current.right).key
else
return specialKey
else
if target < current.key
s = successor(current.left, target)
if s == specialKey
return current.key
else
return s
else
return successor(current.right, target)
Node leftMost(Node current):
while current.left != null
current = current.left
return current
Live Java demo.

These answers all seem overly complicated to me. We really don't need parent pointers or any auxiliary data structures like a stack. All we need to do is traverse the tree from the root in-order, set a flag as soon as we find the target node, and the next node in the tree that we visit will be the in order successor node. Here is a quick and dirty routine I wrote up.
Node* FindNextInorderSuccessor(Node* root, int target, bool& done)
{
if (!root)
return NULL;
// go left
Node* result = FindNextInorderSuccessor(root->left, target, done);
if (result)
return result;
// visit
if (done)
{
// flag is set, this must be our in-order successor node
return root;
}
else
{
if (root->value == target)
{
// found target node, set flag so that we stop at next node
done = true;
}
}
// go right
return FindNextInorderSuccessor(root->right, target, done);
}

JavaScript solution
- If the given node has a right node, then return the smallest node in the right subtree
- If not, then there are 2 possibilities:
- The given node is a left child of the parent node. If so, return the parent node. Otherwise, the given node is a right child of the parent node. If so, return the right child of the parent node
function nextNode(node) {
var nextLargest = null;
if (node.right != null) {
// Return the smallest item in the right subtree
nextLargest = node.right;
while (nextLargest.left !== null) {
nextLargest = nextLargest.left;
}
return nextLargest;
} else {
// Node is the left child of the parent
if (node === node.parent.left) return node.parent;
// Node is the right child of the parent
nextLargest = node.parent;
while (nextLargest.parent !== null && nextLargest !== nextLargest.parent.left) {
nextLargest = nextLargest.parent
}
return nextLargest.parent;
}
}

Doing this in Java
TreeNode getSuccessor(TreeNode treeNode) {
if (treeNode.right != null) {
return getLeftMostChild(treeNode.right);
} else {
TreeNode p = treeNode.parent;
while (p != null && treeNode == p.right) { // traverse upwards until there is no parent (at the last node of BST and when current treeNode is still the parent's right child
treeNode = p;
p = p.parent; // traverse upwards
}
return p; // returns the parent node
}
}
TreeNode getLeftMostChild(TreeNode treeNode) {
if (treeNode.left == null) {
return treeNode;
} else {
return getLeftMostChild(treeNode.left);
}
}

We can divide this in 3 cases:
If the node is a parent: In this case we find if it has a right node and traverse to the leftmost child of the right node. In case the right node has no children then the right node is its inorder successor. If there is no right node we need to move up the tree to find the inorder successor.
If the node is a left child: In this case the parent is the inorder successor.
If the node (call it x) is a right child (of its immediate parent): We traverse up the tree until we find a node whose left subtree has x.
Extreme case: If the node is the rightmost corner node, there is no inorder successor.

Every "tutorial" that I checked on google and all answers in this thread uses the following logic: "If node doesn't have a right child then its in-order suc­ces­sor will be one of its ances­tors. Using par­ent link keep traveling up until you get the node which is the left child of its par­ent. Then this par­ent node will be the in-order successor."
This is the same as thinking "if my parent is bigger than me, then I am the left child" (property of a binary search tree). This means that you can simply walk up the parent chain until the above property is true. Which in my opinion results in a more elegant code.
I guess the reason why everyone is checking "am I the left child" by looking at branches instead of values in the code path that utilizes parent links comes from "borrowing" logic from the no-link-to-parent algorithm.
Also from the included code below we can see there is no need for stack data structure as suggested by other answers.
Following is a simple C++ function that works for both use-cases (with and without utilizing the link to parent).
Node* nextInOrder(const Node *node, bool useParentLink) const
{
if (!node)
return nullptr;
// when has a right sub-tree
if (node->right) {
// get left-most node from the right sub-tree
node = node->right;
while (node->left)
node = node->left;
return node;
}
// when does not have a right sub-tree
if (useParentLink) {
Node *parent = node->parent;
while (parent) {
if (parent->value > node->value)
return parent;
parent = parent->parent;
}
return nullptr;
} else {
Node *nextInOrder = nullptr;
// 'root' is a class member pointing to the root of the tree
Node *current = root;
while (current != node) {
if (node->value < current->value) {
nextInOrder = current;
current = current->left;
} else {
current = current->right;
}
}
return nextInOrder;
}
}
Node* previousInOrder(const Node *node, bool useParentLink) const
{
if (!node)
return nullptr;
// when has a left sub-tree
if (node->left) {
// get right-most node from the left sub-tree
node = node->left;
while (node->right)
node = node->right;
return node;
}
// when does not have a left sub-tree
if (useParentLink) {
Node *parent = node->parent;
while (parent) {
if (parent->value < node->value)
return parent;
parent = parent->parent;
}
return nullptr;
} else {
Node *prevInOrder = nullptr;
// 'root' is a class member pointing to the root of the tree
Node *current = root;
while (current != node) {
if (node->value < current->value) {
current = current->left;
} else {
prevInOrder = current;
current = current->right;
}
}
return prevInOrder;
}
}

C# implementation (Non recursive!) to find the ‘next’ node of a given node in a binary search tree where each node has a link to its parent.
public static Node WhoIsNextInOrder(Node root, Node node)
{
if (node.Right != null)
{
return GetLeftMost(node.Right);
}
else
{
Node p = new Node(null,null,-1);
Node Next = new Node(null, null, -1);
bool found = false;
p = FindParent(root, node);
while (found == false)
{
if (p.Left == node) { Next = p; return Next; }
node = p;
p = FindParent(root, node);
}
return Next;
}
}
public static Node FindParent(Node root, Node node)
{
if (root == null || node == null)
{
return null;
}
else if ( (root.Right != null && root.Right.Value == node.Value) || (root.Left != null && root.Left.Value == node.Value))
{
return root;
}
else
{
Node found = FindParent(root.Right, node);
if (found == null)
{
found = FindParent(root.Left, node);
}
return found;
}
}
public static Node GetLeftMost (Node node)
{
if (node.Left == null)
{
return node;
}
return GetLeftMost(node.Left);
}

Node successor(int data) {
return successor(root, data);
}
// look for the successor to data in the tree rooted at curr
private Node successor(Node curr, int data) {
if (curr == null) {
return null;
} else if (data < curr.data) {
Node suc = successor(curr.left, data);
// if a successor is found use it otherwise we know this node
// is the successor since the target node was in this nodes left subtree
return suc == null ? curr : suc;
} else if (data > curr.data) {
return successor(curr.right, data);
} else {
// we found the node so the successor might be the min of the right subtree
return findMin(curr.right);
}
}
private Node findMin(Node curr) {
if (curr == null) {
return null;
}
while (curr.left != null) {
curr = curr.left;
}
return curr;
}

All right I will take a shot since everyone is posting their implementations. This technique is from Introduction To Algorithms book. Basically, you need a way to backtrack to parent nodes from child nodes.
First up, you need a class to represent nodes:
public class TreeNode<V extends Comparable<V>> {
TreeNode<V> parent;
TreeNode<V> left;
TreeNode<V> right;
V data;
public TreeNode(TreeNode<V> parent, V data) {
this.parent = parent;
this.data = data;
}
public void insert(TreeNode<V> parent, V data) {
if (data.compareTo(this.data) < 0) {
if (left == null) {
left = new TreeNode<>(parent, data);
} else {
left.insert(left, data);
}
} else if (data.compareTo(this.data) > 0) {
if (right == null) {
right = new TreeNode<>(parent, data);
} else {
right.insert(right, data);
}
}
// ignore duplicates
}
#Override
public String toString() {
return data + " -> [parent: " + (parent != null ? parent.data : null) + "]";
}
}
You can have another class to run the operations:
public class BinarySearchTree<E extends Comparable<E>> {
private TreeNode<E> root;
public void insert(E data) {
if (root == null) {
root = new TreeNode<>(null, data);
} else {
root.insert(root, data);
}
}
public TreeNode<E> successor(TreeNode<E> x) {
if (x != null && x.right != null) {
return min(x.right);
}
TreeNode<E> y = x.parent;
while (y != null && x == y.right) {
x = y;
y = y.parent;
}
return y;
}
public TreeNode<E> min() {
return min(root);
}
private TreeNode<E> min(TreeNode<E> node) {
if (node.left != null) {
return min(node.left);
}
return node;
}
public TreeNode<E> predecessor(TreeNode<E> x) {
if(x != null && x.left != null) {
return max(x.left);
}
TreeNode<E> y = x.parent;
while(y != null && x == y.left) {
x = y;
y = y.parent;
}
return y;
}
public TreeNode<E> max() {
return max(root);
}
private TreeNode<E> max(TreeNode<E> node) {
if (node.right != null) {
return max(node.right);
}
return node;
}
}
The idea of finding an accessor is:
if right-subtree is not null, find the minimum value in right-subtree.
else, keep going up the tree till you get to a node that's a left child of its parent.
And for finding a predecessor, it's vice versa.
You can find a complete working example on my GitHub in this package.

In general, queries about n-th smallest (order statistic) element in a tree can be achieved in O(log n) time using an order statistic tree. One implementation is in GNU's C++ extensions: Policy-Based Data Structures. See this CodeForces blog for usage.
The way this is achieved is simply by storing an additional value at each node of a self-balancing tree that is the size of the subtree rooted at that node. Then operations Select(i) which finds the i-th smallest element and Rank(x) which finds the index such that x is the i-th smallest element can be implemented in logarithmic time complexity; see CLRS or the Wikipedia page. Then the query is simply Select(Rank(x)+1).

Related

Binary Search Tree In-order traversal without recursion or additional data structures

If nodes in a Binary Search Tree had pointers back to its parent node, is it possible to do an In-order traversal without the need for recursion or additional data structures?
Keep track of the previous node during the traversal, which will help decide which way to go next.
In C#:
class Node {
/* ... */
public void inorder() {
Node curr = this;
Node prev = null;
Node next = null;
while (curr != null) {
if (curr.right != null && prev == curr.right) {
next = curr.parent;
} else if (curr.left == null || prev == curr.left) {
Console.WriteLine(curr.data); // <-- visit the node.
next = curr.right != null ? curr.right : curr.parent;
} else {
next = curr.left;
}
prev = curr;
curr = next;
}
}
};
In C++ it could look like this:
void inorder(Node* root) {
Node * curr = root;
Node * prev = NULL;
Node * next = NULL;
while (curr != NULL) {
if (curr->right != NULL && prev == curr->right) {
next = curr->parent;
} else if (curr->left == NULL || prev == curr->left) {
cout << curr->data << " "; // <-- visit the node.
next = curr->right != NULL ? curr->right : curr->parent;
} else {
next = curr->left;
}
prev = curr;
curr = next;
}
cout << "\n";
}
To get the first node, you just start at the root and go left as far as possible.
To get from any node to the next:
If the node has a right child, then go right, and then go left as far as possible.
Otherwise, follow parent pointers up until you get to an ancestor on the right (i.e., you get there from a left child)
You're done when you go up from the root.
Here is a small example.
Map<TreeNode,TreeNode> parent; // available
Set<TreeNode> set = new HashSet<>(); // maintain visited nodes
TreeNode curr = root;
while(curr!=null){
if(!set.contains(curr.left) && curr.left!=null){
curr = curr.left;
}else if(!set.contains(curr.right) && curr.right!=null){
System.out.print(curr.value+" ");
curr = curr.right;
}else{
if(curr.right==null){
System.out.print(curr.value+" ");
}
set.add(curr); // mark it as completely visited
curr = parent.get(curr);
}
}

Recursion in Binary Search Tree construction

Below is the code implementation of binary search tree construction in C++. My confusion is I am not able to trace the recursion stack. Consider the below tree. Now I want to remove the node 10. SO this will jump to the line in the code that checks if both left and right subtree are not null and it will try to find the least value in the right subtree and that is 11 in this case. and it will recursively call remove function again . Now I have one doubt - when remove is recursively called again - first it removes 11 from that position in the original tree and return 11 from the function that is received by first remove function on the stack, but then which line in the code actually updates 11 to the root. I am really not getting this in my head. Please help me out.
10
/ \
6 12
\ / \
8 11 15
#include <bits/stdc++.h>
using namespace std;
class BST
{
public:
int value;
BST *left;
BST *right;
BST(int val)
{
value = val;
left = NULL;
right = NULL;
}
BST &insert(int val)
{
BST *currentNode = this; //this points to the current object of BST class. For instance if you created
//root node with value 10. this will store the reference to the root node object
while(true)
{
if (val < currentNode->value) //go to left subtree
{
if (currentNode->left == NULL) //if null insert
{
BST *newNode = new BST(val);
currentNode->left = newNode; //update the address
break;
}
else
{
currentNode = currentNode->left; //if not null then keep traversing
}
}
else
{
if (currentNode->right == NULL)
{
BST *newNode = new BST(val);
currentNode->right = newNode;
break;
}
else
{
currentNode = currentNode->right;
}
}
}
return *this;
}
bool contains(int val)
{
BST *currentNode = this;
while(currentNode != NULL)
{
if (val < currentNode->value)
currentNode = currentNode->left; //if value is less then keep traversing left
else if (val > currentNode->value)
currentNode = currentNode->right; //if value is greater then keep traversing right
else
return true;
}
return false;
}
BST &remove(int val, BST *parentNode = NULL)
{
BST *currentNode = this;
while (currentNode != NULL)
{
if (val < currentNode->value)
{
parentNode = currentNode;
currentNode = currentNode->left;
}
else if (val > currentNode->value)
{
parentNode = currentNode;
currentNode = currentNode->right;
}
//Up until above line the code first searches for the element to be removed
else
{
if (currentNode->left != NULL && currentNode->right != NULL) //this node checks if it has
//left and right child both and if yes then find the least value in the right subtree and then
//remove that node from that position
{
currentNode->value = currentNode->right->getMinValue();
currentNode->right->remove(currentNode->value,currentNode);
}
else if (parentNode == NULL) //this is special case of root node where there may be only
//left child existing or only right child. If both exist then above logic takes care of that
{
if (currentNode->left != NULL)
{
currentNode->value = currentNode->left->value;
currentNode->right = currentNode->left->right;
currentNode->left = currentNode->left->left;
}
else if (currentNode->right != NULL)
{
currentNode->value = currentNode->right->value;
currentNode->left = currentNode->right->left;
currentNode->right = currentNode->right->right;
}
else
{} //This is for single node tree. Do nothing
}
else if (parentNode->left == currentNode) //this condition if the parent node left child is
//the node to be removed . Then we can do simple one liner and update the node
{
parentNode->left = currentNode->left != NULL ? currentNode->left : currentNode->right;
}
else if (parentNode->right == currentNode)
{
parentNode->right = currentNode->left != NULL ? currentNode->left : currentNode->right;
}
break;
}
}
return *this;
}
int getMinValue()
{
if (left == NULL)
return value;
else
return left->getMinValue();
}
void show()
{
BST *currentNode = this;
cout<<currentNode->value;
}
};
int main()
{
int value = 10;
BST b1(value);
b1.insert(12);
b1.insert(6);
b1.insert(8);
b1.insert(15);
b1.insert(11);
b1.remove(10);
b1.show();
}

How do you find the nth node in a binary tree?

I want to find the nth node/element in a binary tree. Not the nth largest/smallest, just the nth in inorder order for example.
How would this be done? Is it possible to keep it to one function? Many functions employ an external variable to keep track of the iterations outside of the recursion, but that seems... lazy, for lack of a better term.
You can augment the binary search tree into an order statistic tree, which supports a "return the nth element" operation
Edit: If you just want the ith element of an inorder traversal (instead of the ith smallest element) and don't want to use external variables then you can do something like the following:
class Node {
Node left
Node right
int data
}
class IterationData {
int returnVal
int iterationCount
}
IterationData findNth(Node node, IterationData data, int n) {
if(node.left != null) {
data = findNth(node.left, data, n)
}
if(data.iterationCount < n) {
data.iterationCount++
if(data.iterationCount == n) {
data.returnVal = node.data
return data
} else if(node.right != null) {
return findNth(node.right, data, n)
} else {
return data
}
}
}
You'll need some way to return two values, one for the iteration count and one for the return value once the nth node is found; I've used a class, but if your tree contains integers then you could use an integer array with two elements instead.
In order iterative traversal, keep track of nodes passed in external variable.
public static Node inOrderInterativeGet(Node root, int which){
Stack<Node> stack = new Stack<Node>();
Node current = root;
boolean done = false;
int i = 1;
if(which <= 0){
return null;
}
while(!done){
if(current != null){
stack.push(current);
current = current.getLeft();
}
else{
if(stack.empty()){
done = true;
}
else{
current = stack.pop();
if(i == which){
return current;
}
i++;
current = current.getRight();
}
}
}
return null;
}
One way to do it is to have a size property which is left_subtree + right_subtree + 1:
class Node:
def __init__(self, data=None, left=None, right=None,
size=None):
self.data = data
self.left = left
self.right = right
self.size = size
def select(node, k):
"""Returns node with k-th position in-order traversal."""
if not node:
return None
t = node.left.size if node.left else 0
if t > k:
return select(node.left, k)
elif t < k:
return select(node.right, k - t - 1)
else:
return node
If you don't like global variable, pass to recursive function additional parameter - some int variable, let's call it auto_increment or just ai. ai stores order of current node. Also, recursive function should return maximal value of ai of current vertex subtree,because after visiting whole subtree next 'free' value will be max_ai_in_subreee+1 Something like that
int rec(int vertex,int ai){
traverseOrder[vertex] = ai
if(getChildren(vertex)!=null) return ai;
else{
for(childrens){
ai = rec(child,ai+1);
}
return ai;// subtree visited, return maximal free value upstairs.
}
}
If your function already returns some useful data, it may return some complex object which contains {useful data+ai}
Start from some vertex looks like rec(start_vertex,1);
Below is full code that you can use to find the nth element using inorder in a Binary Tree.
public class NthNodeInInoeder {
static public class Tree {
public int data;
public Tree left,right;
public Tree(int data) {
this.data = data;
}
}
static Tree root;
static int count = 0;
private static void inorder(Tree root2, int num) {
if (root2 == null)
return;
Tree node = root2;
Stack<Tree> stack = new Stack<>();
while (node != null || stack.size() > 0) {
while (node != null) {
stack.push(node);
node = node.left;
}
node = stack.pop();
count++;
if (count == num) {
System.out.println(node.data);
break;
}
node = node.right;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
root = new Tree(10);
root.left = new Tree(20);
root.right = new Tree(30);
root.left.left = new Tree(40);
root.left.right = new Tree(50);
int num = sc.nextInt();
inorder(root, num);
sc.close();
}
}

Min Depth of binary tree

I am reading Binary Trees. while practicing coding problems I came across some solutions where it is asked to find Min Depth of Binary Tree.
Now as per my understanding depth is no of edges from root to node (leaf node in case of leaf nodes / binary tree)
What is the min depth of Binary tree {1,2}
As per my solution it should be 1.
My tested solution
public int minDepth(TreeNode root) {
if(root == null){
return 0;
}
int ldepth = minDepth(root.left);
int rdepth = minDepth(root.right);
if(ldepth == 0){
return 1+rdepth;
}else if(rdepth == 0){
return 1+ldepth;
}
return (1 + Math.min(rdepth, ldepth));
}
Here, we calculate ldepth (minimum left subtree depth) and rdepth (minimum right subtree depth) for a node. Then, if ldepth is zero but rdepth is not, that means current node is not a leaf node, so return 1 + rdepth. If both rdepth and ldepth are zeros then still 'if' condition works as we return 1+0 for current leaf node.
Similar logic for 'else if' branch. In 'return' statement as both 'if' conditions has been failed we return 1 (current node) + minimum value of recursive calls to both left and right branch.
Remember a leaf node has neither left nor right child.
1
/
/
2
so here 2 is the leaf node but 1 is not. so minimum depth for this case is 2 assuming depth of root node is 1.
#include<vector>
#include<iostream>
#include<climits>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
int minDepth(TreeNode *root) {
if(root == NULL) return 0;
return getDepth(root);
}
int getDepth(TreeNode *r ){
if(r == NULL) return INT_MAX;
if(r->left == NULL && r->right == NULL)
return 1;
return 1+ min(getDepth(r->left), getDepth(r->right));
}
};
A root node will have a depth of 0, so here depth of the given tree will be 1, refer below recursion and iterative solution to find min dept of binary tree.
Recursive solution :
public static int findMinDepth(BTNode root) {
if (root == null || (root.getLeft() == null && root.getRight() == null)) {
return 0;
}
int ldepth = findMinDepth(root.getLeft());
int rdepth = findMinDepth(root.getRight());
return (Math.min(rdepth + 1, ldepth + 1));
}
Iterative solution :
public static int minDepth(BTNode root) {
int minDepth = Integer.MAX_VALUE;
Stack<BTNode> nodes = new Stack<>();
Stack<BTNode> path = new Stack<>();
if (root == null) {
return -1;
}
nodes.push(root);
while (!nodes.empty()) {
BTNode node = nodes.peek();
if (!path.empty() && node == path.peek()) {
if (node.getLeft() == null && node.getRight() == null && path.size() <= minDepth) {
minDepth = path.size() - 1;
}
path.pop();
nodes.pop();
} else {
path.push(node);
if (node.getRight() != null) {
nodes.push(node.getRight());
}
if (node.getLeft() != null) {
nodes.push(node.getLeft());
}
}
}
return minDepth;
}
The depth o a binary tree is the length of the longest route from the root to the leaf. In my opinion the depth should be 2.
public int minDepth(TreeNode root){
if(root==null)
return 0;
else if(root.left==null && root.right==null)
return 1;
else if(root.left==null)
return 1+minDepth(root.right);
else if(root.right==null)
return 1+minDepth(root.left);
else
return 1+Math.min(minDepth(root.right), minDepth(root.left));
}
As others stated, solution should be 2... But it's semantic, you could simply take result and subtract 1 if your definition of depth is different.
Here's an iterative answer (in C#) (Rajesh Surana answer is a good Recusive answer):
public static int FindMinDepth<T>(BinarySearchTree<T> tree) where T : IComparable<T>
{
var current = tree._root;
int level = 0;
Queue<BSTNode<T>> q = new Queue<BSTNode<T>>();
if (current != null)
q.Enqueue(current);
while (q.Count > 0)
{
level++;
Queue<BSTNode<T>> nq = new Queue<BSTNode<T>>();
foreach (var element in q)
{
if (element.Left == null && element.Right == null)
return level;
if (element.Left != null) nq.Enqueue(element.Left);
if (element.Right != null) nq.Enqueue(element.Right);
}
q = nq;
}
return 0;
//throw new Exception("Min Depth not found!");
}
JavaScript Solution
Given the following Binary Tree structure:
function BT(value, left = null, right = null) {
this.value = value;
this.left = left;
this.right = right;
}
A method to find the minimum depth can be something like so:
BT.prototype.getMinDepth = function() {
if (!this.value) {
return 0;
}
if (!this.left && !this.right) {
return 1;
}
if (this.left && this.right) {
return Math.min(this.left.getMinDepth(), this.right.getMinDepth()) + 1;
}
if (this.left) {
return this.left.getMinDepth() + 1;
}
if (this.right) {
return this.right.getMinDepth() + 1;
}
}
The time complexity of the above solution is O(n) as it traverses all the tree nodes.
A better runtime solution will be to use a breadth traversal method that ends when reaching the first leaf node:
BT.prototype.getMinDepth = function(depth = 0) {
if (!this.value) {
return depth;
}
depth++;
if (!this.left || !this.right) {
return depth;
}
return Math.min(this.left.getMinDepth(depth), this.right.getMinDepth(depth));
}
Given the depth of a path is the number of nodes from the root to the leaf node along this path. The minimum is the path with minimum number of nodes from the root to the LEAF node. In this case, the only leaf node is 2. (A leaf node is defined as a node with no children) Therefore, the only depth and also min depth is 2.
A sample code in Java:
public class Solution {
public int minDepth(TreeNode root) {
if (root==null) return 0;
if ((root.left==null) || (root.right==null)) {
return 1+Math.max(minDepth(root.left),minDepth(root.right));
}
return 1+Math.min(minDepth(root.left),minDepth(root.right));
}
}
Minimum depth is the minimum of the depth of leftsubtree and rightsubtree.
public static int maxDepth(TreeNode root) {
if(root == null) {
return 0;
}
return getDepth(root);
}
private static int getDepth(TreeNode a) {
if(a.left == null & a.right == null) {
return 1;
}
int leftDepth = 0;
int rightDepth = 0;
if(a.left != null) {
leftDepth = getDepth(a.left);
}
if(a.right != null) {
rightDepth = getDepth(a.right);
}
return (Math.min(leftDepth, rightDepth)+1);
}
The minDepth of a binary tree means the shortest distance from the root to a leaf node. Though it is arguable whether the minDepth of your binary tree is 1 or 2, depending on whether you want the shortest distance to a null node, in which case the answer would be 1 OR the shortest distance to a null node whose sibling is ALSO a null node, in which case the answer to Binary tree{1,2} would be 2. Generally, the former is asked, and following the algorithm mentioned in Cracking the Coding Interview , we have the solution as
int minDepth(TreeNode root) {
if (root == null) { return 0;}
return 1 + Math.min(minDepth(root.left), minDepth(root.right));
}

Second max in BST

This is an interview question. Find the second max in BST.
The max element is the rightmost leaf in the BST. The second max is either its parent or its left child. So the solution is to traverse the BST to find the rightmost leaf and check its parent and left child.
Does it make sense?
No, that's wrong. Consider this BST:
137
/
42
\
99
Here, the second-to-max value is the rightmost child of the left child of the max value. Your algorithm will need to be updated so that you check the parent of the max value, or the rightmost subchild of the left child of the max.
Also, note that the max is not necessarily the rightmost leaf node, it's the node at the bottom of the right spine of the tree. Above, 137 is not a leaf.
Hope this helps!
Recall that you can list the nodes of a BST in reverse order by doing a modified inorder traversal where you explore the right subtree first. This leads to a simple algorithm:
Node rightmost = findRightmostNode(root)
if (rightmost.left != null) {
return findRightmostNode(rightmost.left)
else{
return rightmost.parent
}
It would return null if the tree has only one element.
public static int findSecondLargestValueInBST(Node root)
{
int secondMax;
Node pre = root;
Node cur = root;
while (cur.Right != null)
{
pre = cur;
cur = cur.Right;
}
if (cur.Left != null)
{
cur = cur.Left;
while (cur.Right != null)
cur = cur.Right;
secondMax = cur.Value;
}
else
{
if (cur == root && pre == root)
//Only one node in BST
secondMax = int.MinValue;
else
secondMax = pre.Value;
}
return secondMax;
}
Much easier iterative approach with Time complexity O(logN) and Space complexity O(1)
public static void main(String[] args) {
BinaryTreeNode result=isBinarySearchTree.secondLargest(rootNode);
System.out.println(result.data);
}
private BinaryTreeNode secondLargest(BinaryTreeNode node) {
BinaryTreeNode prevNode=null; //2nd largest Element
BinaryTreeNode currNode=node;
if(null == currNode)
return prevNode;
while(currNode.right != null){
prevNode=currNode;
currNode=currNode.right;
}
if(currNode.left != null){
currNode=currNode.left;
while(currNode.right != null){
currNode=currNode.right;
}
prevNode=currNode;
}
return prevNode;
}
The algo can be as follows
1. find the largest number in the tree.
private static int findLargestValueInTree(Node root) {
while (root.right != null) {
root = root.right;
}
return root.data;
}
2. Find the largest number in the tree that is smaller than the number we found in step 1
public static int findSecondLargest(Node root, int largest, int current) {
while (root != null) {
if (root.data < largest) {
current = root.data;
root = root.right;
} else {
root = root.left;
}
}
return current;
}
'current' keeps track of the current largest number which is smaller than the number found in step1
Simple javascript implementation.
function Node (value, left, right) {
this.value = value;
this.left = left;
this.right = right;
}
function second (node, prev, wentLeft) {
if (node.right) {
return second(node.right, node, wentLeft);
} else if (node.left) {
return second(node.left, node, true);
} else {
if (wentLeft) return node.value;
return prev.value;
}
}
second(root);
One traversal variant:
public Tree GetSecondMax(Tree root)
{
Tree parentOfMax = null;
var maxNode = GetMaxNode(root, ref parentOfMax);
if (maxNode == root || maxnode.left != null)
{
// if maximum node is root or have left subtree, then return maximum from left subtree
return GetMaxNode(maxnode.left, ref parentOfMax);
}
// if maximum node is not root, then return parent of maximum node
return parentOfMax;
}
private Tree GetMaxNode(Tree root, ref Tree previousNode)
{
if (root == null || root.right == null)
{
// The most right element have reached
return root;
}
// we was there
previousNode = root;
return GetMaxNode(root.right, ref previousNode);
}
int getmax(node *root)
{
if(root->right == NULL)
{
return root->d;
}
return getmax(root->right);
}
int secondmax(node *root)
{
if(root == NULL)
{
return -1;
}
if(root->right == NULL && root->left != NULL)
{
return getmax(root->left);
}
if(root->right != NULL)
{
if(root->right->right == NULL && root->right->left == NULL)
{
return root->d;
}
}
return secondmax(root->right);
}
A very intuitive way to think about this is considering the following two cases.
Let second largest Node as S, and largest node as L.
i) S is inserted to the BST "earlier" than L.
ii) S is inserted to the BST "later" than L.
For the first case, it is obvious that L is the right child of S. It is because any node except for L is smaller than S, therefore will not be put on the right side of S. Therefore when L is being put, it will be the right child of S.
For the second case, by the time when S is inserted, L will the be right most node in the BST. Obviously, L wouldn't have a right child because it is the largest. However, L could have its own left subtree. When S is inserted, S will follow to "right path" until it meets L and then turn left to go to the left subtree of L. Here, we know that all of the nodes in L's left subtree are smaller than S, so S will be the rightmost node in the subtree.
int getSecondLargest(Node root){
if(root==null)
return 0;
Node curr=root;
Node prev=root;
//Go to the largest node
while(curr.right != null){
prev = curr;
curr= curr.right;
}
//If largest Node has left child, Then largest element of tree with its root as largest.left will be the second largest number.
if(curr.left == null)
return prev.data;
else
return findLargest(curr.left);
}
int findLargest(Node root){
// No need toi check for null condition as in getSecondLargest method, its already done.
Node curr=root;
//To find largest just keep on going to right child till leaf is encountered.
while(curr.right != null){
curr = curr.right;
}
return curr.data;
}
I would do it by going though the tree from biggest to smallest element and returning value when asked position is reached. I implemented similar task for second largest value.
void BTree::findSecondLargestValueUtil(Node* r, int &c, int &v)
{
if(r->right) {
this->findSecondLargestValueUtil(r->right, c, v);
}
c++;
if(c==2) {
v = r->value;
return;
}
if(r->left) {
this->findSecondLargestValueUtil(r->left, c, v);
}
}
int BTree::findSecondLargestValue()
{
int c = 0;
int v = -1;
this->findSecondLargestValueUtil(this->root, c, v);
return v;
}
You are close to the right answer.
Here is my attempt at an intuitive answer.
The greatest node is the right most node.
Whatever is under the right most node's left sub-tree is greater than all elements except the right most node. Therefore the greatest node in this sub-tree is the answer.
If there is no left sub-tree then the parent of the right most node is the one that is greater than all the other nodes except the right most node.
The idea is to go all the way to the right until there is nothing on the right. If there's a left, take it and then go all the way to the right. If you took a left, the answer is the last node encountered. Otherwise the answer is the second-last node you encountered.
Here's a recursive solution in Java:
public TreeNode getSecondLargest(TreeNode root) {
if(root == null || (root.left == null && root.right == null))
throw new IllegalArgumentException("The tree must have at least two nodes");
return helper(root, null, false);
}
private TreeNode helper(TreeNode root, TreeNode parent, boolean wentLeft) {
if(root.right != null) return helper(root.right, root, wentLeft);
if(root.left != null && !wentLeft) return helper(root.left, root, true);
if(wentLeft) return root;
else return parent;
}
The time complexity is O(lg n).
This Algorithm to find 2nd Max Element in a BST , will take Time Complexity: O(n) --> in worst case where tree is a right skew tree.
And if the Tree is balanced Tree then the Time Complexity is O(height)
ie O(log n)
And Same Goes with Space Complexity as well: O(n) --> in worst case
O(log n) --> when Tree is balanced.
public TreeNode secondMax(TreeNode root){
return helper(root,null);
}
private TreeNode helper(TreeNode root,TreeNode prev){
if(root==null)
return root;
if(root.right==null && root.left!=null)
return root.left;
else if(root.right==null && root.left==null)
return prev;
return helper(root.right,root);
}
This algorithm does one run on the tree and returns the largest item at Item1 and second largest at Item2.
The sort calls are O(1) because they are independent of the tree size.
So the total time complexity is O(N) and space complexity is O(log(N)) when the tree is balanced.
public static Tuple<int, int> SecondLargest(TreeNode<int> node)
{
int thisValue = node.Value;
if ((node.Left == null || node.Left.Right == null) && node.Right == null)
{
return new Tuple<int, int>(thisValue, -int.MaxValue);
}
else if (node.Left == null || node.Left.Right == null)
{
Tuple<int, int> right = SecondLargest(node.Right);
List<int> sortLargest = new List<int>(new int[] { right.Item1, right.Item2, thisValue });
sortLargest.Sort();
return new Tuple<int, int>(sortLargest[2], sortLargest[1]);
}
else if (node.Right == null)
{
Tuple<int, int> left = SecondLargest(node.Left.Right);
List<int> sortLargest = new List<int>(new int[] { left.Item1, left.Item2, thisValue });
sortLargest.Sort();
return new Tuple<int, int>(sortLargest[2], sortLargest[1]);
}
else
{
Tuple<int, int> left = SecondLargest(node.Left.Right);
Tuple<int, int> right = SecondLargest(node.Right);
List<int> sortLargest = new List<int>(new int[] { left.Item1, left.Item2, right.Item1, right.Item2, thisValue });
sortLargest.Sort();
return new Tuple<int, int>(sortLargest[4], sortLargest[3]);
}
}

Resources