# Sucesor en orden en el árbol de búsqueda binaria

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

preguntado el 29 de marzo de 11 a las 12:03

`if (node->right) return min_tree(node->right);` What if the node has no right sub-tree? -

## 19 Respuestas

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): 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.

respondido 29 mar '11, 12:03

great answer! can you please explain the first way once more...in a bit more detail would be great. thank you so much. - mateo kurian

Just wanted to add... 1. Basically, the right goes up until the parent's left is the child. However, if there is a right. It will go all the way to the down to the left most in the right side! - mateo kurian

@Lasse V. Karlsen If you don't have parent pointers, you can still find the in-order successor in O(h) time, where h is the height of the tree. As you find the node, keep track of last node from which you stepped to a left child. This node is the in-order successor when a node has no right child. If a node has a right child, the in-order successor is the minimum node in the right subtree. - Juan Kurlak

Agree with @JohnKurlak Here's a gist in Java implementing without parent pointers. gist.github.com/rcaloras/36f9e5f94f4334e0827c5b52ec0d8115 - RCCola

@RCCola This solution is not quite the same as JohnKurlak's because it begins searching from root when the right subtree is null. Here is a jsfiddle example with keeping track of the node last stepped left from: jsfiddle.net/e3d8Lvu5/4 - bennett molinero

Python code to the Lasse's https://www.youtube.com/watch?v=xB-eutXNUMXJtA&feature=youtu.be:

``````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
``````

Respondido el 12 de diciembre de 20 a las 12:12

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);
for(int i = 0; i <= 7; i++) {
}
}
}
``````

Respondido 27 Abr '12, 21:04

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.

respondido 29 mar '11, 12:03

This algorithm depends on the parent link, the implementation if you don't have that is quite different. - Lasse V. Karlsen

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:

1. Start with the right child of the given node (make it the temporary current node)
2. If the current node has no left child, it is the next highest node.
3. If the current node has a left child, make it the current node.

Repeat 2 and 3 until we find next highest node.

respondido 02 nov., 12:19

In a tree with three nodes, a parent and two children, this algorithm would fail on the left child. It ignores walking back up the tree. - Craig P. Motlin

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.

Respondido 03 Jul 18, 21:07

## 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;
}
``````

Que imprime:

``````1 2 3 4 5 6 7 8 9 10 11

unit tests:
passed01
passed02
passed03
passed04
passed05
passed06
passed07
passed08
passed09
``````

Respondido 16 Jul 13, 19:07

``````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
``````

Respondido 07 Oct 14, 11:10

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

Respondido el 10 de enero de 15 a las 20:01

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.

Pseudocódigo:

``````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
``````

Respondido el 31 de diciembre de 17 a las 16:12

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

Respondido el 09 de diciembre de 14 a las 05:12

The big O would be O(n), let's do better. See @Lasse V. Karlsen's answer. - Alan Dong

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

Respondido 19 Oct 15, 04:10

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

respondido 22 nov., 16:04

We can divide this in 3 cases:

1. 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.

2. If the node is a left child: In this case the parent is the inorder successor.

3. 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.

respondido 30 nov., 16:10

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 como lo sugieren otras respuestas.

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

Respondido el 02 de enero de 17 a las 12:01

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

respondido 16 mar '17, 07:03

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

respondido 23 mar '20, 00:03

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.

Respondido 11 Feb 21, 18:02

In general, queries about n-th smallest (order statistic) element in a tree can be achieved in O(log n) time using an orden árbol de estadísticas. One implementation is in GNU's C++ extensions: Policy-Based Data Structures. Vea this CodeForces blog para su uso.

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)`.

Respondido 16 Oct 21, 09:10

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.