Given a node in a BST, how does one find the next higher key?
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;
}
}
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
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.
Python code to the Lasse's answer:
def findNext(node):
if node.rightChild != None:
return findMostLeft(node.rightChild)
else:
parent = node.parent
while parent != None:
if parent.leftChild == node:
break
node = parent
parent = node.parent
return parent
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);
}