In Order Successor in Binary Search Tree

前端 未结 17 1772
孤独总比滥情好
孤独总比滥情好 2020-11-27 04:11

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

相关标签:
17条回答
  • 2020-11-27 04:51

    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;
      }
    }
    
    0 讨论(0)
  • 2020-11-27 04:52

    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
    
    0 讨论(0)
  • 2020-11-27 04:52

    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.

    0 讨论(0)
  • 2020-11-27 04:56

    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
    
    0 讨论(0)
  • 2020-11-27 04:56

    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);
        }
    
    0 讨论(0)
提交回复
热议问题