Search code examples
c++rotationbinary-search-treevoid

Rotate right in a BST using void


I am not implementing an AVL tree but I need to create a method that would rotate the binary search tree to right, However, I used the following code and the solution is not working.

How do I implement the rotate right method including rotating the root node and the non-root node?


void BST<T>::rotate_right(Node* node)
{
    //Node * current = node;
    Node * move_up_node = node->left;
    
    if(node == nullptr || move_up_node == nullptr)
    {
       return;
    }
    else
    {
       node->left = move_up_node->right;        
       if(node->left != nullptr)
       {
           node->left->parent = node;
       }
        //set parent edge
       move_up_node->parent = node->parent;
                   
       if(node == root_)
       {
           root_ = move_up_node;
       }
       
       else if(node == node->parent->right)
       {
           node->parent->right = move_up_node;
       }
       else if (node == node->parent->left)
       {
           node->parent->left = move_up_node;
       }
        
       node->parent = move_up_node;
       move_up_node->right = node;
        //node = move_up_node;
    }
    
    // Correct height of ancestors of node
     fix_height(root_);
}

The rotate node input is 21 When I output it, it does not do anything.

Before I tested the function, the output was

 10 Height: 5
   R├──42 Height: 4
    |  R├──91 Height: 3
    |   |  L└──49 Height: 2
    |   |     R└──70 Height: 1
    |   |      |  R├──77 Height: 0
    |   |      |  L└──54 Height: 0
    |  L└──21 Height: 0
   L└──1 Height: 2
      R└──7 Height: 1
       |  L└──2 Height: 0

After I tested it, the output was

rotate node: 21
 10 Height: 5
   R├──42 Height: 4
    |  R├──91 Height: 3
    |   |  L└──49 Height: 2
    |   |     R└──70 Height: 1
    |   |      |  R├──77 Height: 0
    |   |      |  L└──54 Height: 0
    |  L└──21 Height: 0
   L└──1 Height: 2
      R└──7 Height: 1
       |  L└──2 Height: 0


Solution

  • There are these issues in the outer else block:

    • move_up_node->parent->right = node is not right, as move_up_node is node->left, and so move_up_node->parent is node, which means you actually set node->right = node, which creates a loop. What you really want here is node->left->parent = node

    • if(node == node->parent->right) is not safe if you don't first verify node has a parent. So make this an else if.

    • node->right = move_up_node is not right (it doesn't move that node up as the name suggests). It should be node->parent->right = move_up_node. The same mistake occurs in the next block.

    Here is a correction of that outer else block:

            // Set edge between node and its current inner grandchild:
            node->left = move_up_node->right;
            if (node->left != nullptr) {
                node->left->parent = node;  // <---
            }
            // Set edge between parent of node and the node that moves up
            move_up_node->parent = node->parent;
            if(node == root_)
            {
                root_ = move_up_node;
            }
            else if(node == node->parent->right)  // <-- else!
            {
                node->parent->right = move_up_node; // <--
            }
            else // <-- no need for another `if`
            {
                node->parent->left = move_up_node; // <--
            }
            // Set edge between node and move_up_node (was OK):
            node->parent = move_up_node;
            move_up_node->right = node;