In Order Successor in Binary Search Tree

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

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

17条回答
  •  不知归路
    2020-11-27 04:38

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

提交回复
热议问题