Algorithm Implementation/Trees/AVL tree

      A C++ implementation

      // NOTE: All the member functions are inline in the following code.
      //       This is not recommended. Only simple straight forward functions should be made inline.
      class AVLTree
      {
              private:
                      class Node
                      {
                              private:
                                      int data;
                                      int height;
                                      Node * parent;
                                      Node * left_child;
                                      Node * right_child;
                              public:
                                      Node(int val)
                                      {
                                              data = val;
                                              height = 0;
                                              parent = (Node*)0;
                                              left_child = (Node*)0;
                                              right_child = (Node*)0;
                                      }
                                      int getData()
                                      {
                                              return data;
                                      }
                                      int getHeight()
                                      {
                                              return height;
                                      }
                                      int updateHeight()
                                      {
                                              if(left_child != 0 && right_child != 0)
                                              {
                                                      if(left_child->getHeight() > right_child->getHeight())
                                                              height = left_child->getHeight() + 1;
                                                      else
                                                              height = right_child->getHeight() + 1;
                                              }
                                              else if(left_child != 0)
                                                      height = left_child->getHeight() + 1;
                                              else if(right_child != 0)
                                                      height = right_child->getHeight() + 1;
                                              else
                                                      height = 0;
                                              return height;
                                      }
                                      int getBalance()
                                      {
                                              Node * n = this;
                                              if(n->getLeftChild() != 0 && n->getRightChild() !=0)
                                                      return n->getLeftChild()->getHeight() - n->getRightChild()->getHeight();
                                              else if(n->getLeftChild() != 0)
                                                      return n->getLeftChild()->getHeight() + 1;
                                              else if(n->getRightChild() != 0)
                                                      return (-1) * (n->getRightChild()->getHeight() + 1);
                                              else
                                                      return 0;
                                      }
                                      Node* getParent()
                                      {
                                              return parent;
                                      }
                                      void removeParent()
                                      {
                                              parent = (Node*)0;
                                      }
                                      Node* getLeftChild()
                                      {
                                              return left_child;
                                      }
                                      Node* setLeftChild(Node* new_left)
                                      {
                                              if(new_left != 0) new_left->parent = this;
                                              left_child = new_left;
                                              updateHeight();
                                              return left_child;
                                      }
                                      Node* getRightChild()
                                      {
                                              return right_child;
                                      }
                                      Node* setRightChild(Node* new_right)
                                      {
                                              if(new_right != 0) new_right->parent = this;
                                              right_child = new_right;
                                              updateHeight();
                                              return right_child;
                                      }
                      };
       
                      void setRoot(Node* n)
                      {
                              root = n;
                              if(root != 0) root->removeParent();
                      }
       
       
                      Node* findNode(int val)
                      {
                              Node* temp = root;
                              while(temp != 0)
                              {
                                      if(val == temp->getData())
                                              return temp;
       
                                      else if(val < temp->getData())
                                              temp = temp->getLeftChild();
       
                                      else
                                              temp = temp->getRightChild();
                              }
                              return (Node*)0;
                      }
                      void rotateLeft(Node * n)
                      {
                              Node * p = n->getParent();
                              enum {left, right} side;
                              if(p != 0)
                              {
                                      if(p->getLeftChild() == n)
                                              side = left;
                                      else
                                              side = right;
                              }
                              Node * temp = n->getRightChild();
                              n->setRightChild(temp->getLeftChild());
                              temp->setLeftChild(n);
                              // Now attach the subtree to the parent (or root)
                              if(p != 0)
                              {
                                      if(side == left)
                                              p->setLeftChild(temp);
                                      if(side == right)
                                              p->setRightChild(temp);
                              }
                              else
                              {
                                      setRoot(temp);
                              }
                      }
       
                      void rotateRight(Node * n)
                      {
                              Node * p = n->getParent();
                              enum {left, right} side;
                              if(p != 0)
                              {
                                      if(p->getLeftChild() == n)
                                              side = left;
                                      else
                                              side = right;
                              }
                              Node * temp = n->getLeftChild();
                              n->setLeftChild(temp->getRightChild());
                              temp->setRightChild(n);
                              // Now attach the subtree to the parent (or root)
                              if(p != 0)
                              {
                                      if(side == left)
                                              p->setLeftChild(temp);
                                      if(side == right)
                                              p->setRightChild(temp);
                              }
                              else
                              {
                                      setRoot(temp);
                              }
                      }
       
                      // This function does balancing at the given node
                      void balanceAtNode(Node* n)
                      {                       
                              int bal = n->getBalance();
                              if(bal > 1)
                              {
                                      if(n->getLeftChild()->getBalance() < 0)
                                              rotateLeft(n->getLeftChild());
                                      rotateRight(n);
                              }
                              else if(bal < -1)
                              {
                                      if(n->getRightChild()->getBalance() > 0)
                                              rotateRight(n->getRightChild());
                                      rotateLeft(n);
                              }
                      }
       
                      Node * root;
       
              public:
                      AVLTree()
                      {
                              root = (Node*)0;
                      }
       
                      AVLTree(int val)
                      {
                              root = new Node(val);
                      }
       
                      AVLTree * findSubtree(int val)
                      {
                              Node* target;
                              target = findNode(val);
       
                              if(target != 0)
                              {
                                      AVLTree* subtree = new AVLTree();
                                      subtree->root = target;
                                      return subtree;
                              }
                              else
                                      return (AVLTree*)0;
                      }
       
                      // Returns:
                      //              true: If addition is successful
                      //              false: If item already exists
                      //
                      bool insert(int val)
                      {
                              Node* added_node;
                              if(root == 0)
                              {
                                      root = new Node(val);
                                      return true;
                              }
                              else
                              {
                                      Node* temp = root;
       
                                      while(true)
                                      {
                                              if(temp->getData() > val)
                                              {
                                                      if((temp->getLeftChild()) == 0)
                                                      {
                                                              added_node = temp->setLeftChild(new Node(val));
                                                              break;
                                                      }
                                                      else
                                                      {
                                                              temp = temp->getLeftChild();
                                                      }
       
                                              }
                                              else if(temp->getData() < val)
                                              {
                                                      if((temp->getRightChild()) == 0)
                                                      {
                                                              added_node = temp->setRightChild(new Node(val));
                                                              break;
                                                      }
                                                      else
                                                      {
                                                              temp = temp->getRightChild();
                                                      }
       
                                              }
                                              else
                                              {
                                                      return false;
                                              }
                                      }
                                      // The following code is for updating heights and balancing.
                                      temp = added_node;
                                      while(temp != 0)
                                      {
                                              temp->updateHeight();
                                              balanceAtNode(temp);
                                              temp = temp->getParent();
                                      }
                              }
                      }
       
                      // Returns:
                      //              true: If removal is successful
                      //              false: If item is not found in the tree
                      //
                      bool remove(int val)
                      {
                              if(root == 0) return false;
                              Node *replacement, *replacement_parent, *temp_node;
                              Node * to_be_removed = findNode(val);                   
                              if(to_be_removed == 0) return false;
       
                              Node * p = to_be_removed->getParent();
       
                              enum {left, right} side;
                              if(p != 0)
                              {
                                      if(p->getLeftChild() == to_be_removed) side = left;
                                      else side = right;
                              }
       
                              int bal = to_be_removed->getBalance();
       
                              if(to_be_removed->getLeftChild() == 0 && to_be_removed->getRightChild() == 0)
                              {
                                      if(p != 0)
                                      {
                                              if(side == left) p->setLeftChild((Node*)0);
                                              else p->setRightChild((Node*)0);
       
                                              delete to_be_removed;
                                              p->updateHeight();
                                              balanceAtNode(p);
                                      }
                                      else
                                      {
                                              setRoot((Node*)0);
                                              delete to_be_removed;
                                      }
       
                              }
                              else if(to_be_removed->getRightChild() == 0)
                              {
                                      if(p != 0)
                                      {
                                              if(side == left) p->setLeftChild(to_be_removed->getLeftChild());
                                              else p->setRightChild(to_be_removed->getLeftChild());
       
                                              delete to_be_removed;
                                              p->updateHeight();
                                              balanceAtNode(p);
                                      }
                                      else
                                      {
                                              setRoot(to_be_removed->getLeftChild());
                                              delete to_be_removed;
                                      }
                              }
       
                              else if(to_be_removed->getLeftChild() == 0)
                              {
                                      if(p != 0)
                                      {
                                              if(side == left) p->setLeftChild(to_be_removed->getRightChild());
                                              else p->setRightChild(to_be_removed->getRightChild());
       
                                              delete to_be_removed;
                                              p->updateHeight();
                                              balanceAtNode(p);
                                      }
                                      else
                                      {
                                              setRoot(to_be_removed->getRightChild());
                                              delete to_be_removed;
                                      }
                              }
                              else
                              {
                                      if(bal > 0)
                                      {
                                              if(to_be_removed->getLeftChild()->getRightChild() == 0)
                                              {
                                                      replacement = to_be_removed->getLeftChild();
                                                      replacement->setRightChild(to_be_removed->getRightChild());
       
                                                      temp_node = replacement;
       
       
                                              }
                                              else
                                              {
                                                      replacement = to_be_removed->getLeftChild()->getRightChild();
                                                      while(replacement->getRightChild() != 0)
                                                      {
                                                              replacement = replacement->getRightChild();
                                                      }
                                                      replacement_parent = replacement->getParent();
                                                      replacement_parent->setRightChild(replacement->getLeftChild());
       
                                                      temp_node = replacement_parent;
       
                                                      replacement->setLeftChild(to_be_removed->getLeftChild());
                                                      replacement->setRightChild(to_be_removed->getRightChild());
                                              }
                                      }
                                      else
                                      {
                                              if(to_be_removed->getRightChild()->getLeftChild() == 0)
                                              {
                                                      replacement = to_be_removed->getRightChild();
                                                      replacement->setLeftChild(to_be_removed->getLeftChild());
       
                                                      temp_node = replacement;
       
       
                                              }
                                              else
                                              {
                                                      replacement = to_be_removed->getRightChild()->getLeftChild();
                                                      while(replacement->getLeftChild() != 0)
                                                      {
                                                              replacement = replacement->getLeftChild();
                                                      }
                                                      replacement_parent = replacement->getParent();
                                                      replacement_parent->setLeftChild(replacement->getRightChild());
       
                                                      temp_node = replacement_parent;
       
                                                      replacement->setLeftChild(to_be_removed->getLeftChild());
                                                      replacement->setRightChild(to_be_removed->getRightChild());
                                              }
                                      }               
                                      if(p != 0)
                                      {
                                              if(side == left) p->setLeftChild(replacement);
                                              else p->setRightChild(replacement);
       
                                              delete to_be_removed;
                                      }
                                      else
                                      {
                                              setRoot(replacement);
                                              delete to_be_removed;
                                      }
       
                                      balanceAtNode(temp_node);
                              }
       
                      }
                      int getHeight()
                      {
                              return root->getHeight();
                      }
      };
      
      ↑Jump back a section
      Last modified on 9 September 2012, at 11:54