Реализация AVL Tree - PullRequest
       29

Реализация AVL Tree

0 голосов
/ 02 августа 2020

Я пытаюсь реализовать дерево AVL. Существует функция добавления узла для добавления узлов в дерево, которая в дальнейшем вызывает функцию ребалансировки, чтобы проверить коэффициент баланса добавляемых узлов. Функция добавления работает правильно, но не происходит перестановки узлов, даже если коэффициент баланса выходит за пределы диапазона [-1,1]. Обход порядка уровней возвращает одно и то же дерево каждый раз даже после добавления узлов.

template<class T>
class avl{
    private:
     Node<T>* root;
     
     //REBALANCE FUNCTION
     Node<T>* rebalance(Node<T>* &node){
      int bal_fact=balance_factor(node);
       if(bal_fact>1){
           if(balance_factor(node->m_left)>0){
             node=ll_rotate(node);
           }else{
             node=lr_rotate(node);
           }
       }
       if(bal_fact<-1){
          if(balance_factor(node->m_right)>0){
             node=rl_rotate(node);
           }else{
             node=rr_rotate(node);
           }
       }
       return node;
     }
     //HEIGHT FUNCTION
     int height(Node<T>* node){
          if(node==nullptr){return 0;}
          int l_height=height(node->m_left);
          int r_height=height(node->m_right);
        if(l_height>=r_height){return l_height+1;}
        else{return r_height+1;}
      }


    //balance_factor
      int balance_factor(Node<T>* node){
        
          int l_height= height(node->m_left);
          int r_height= height(node->m_right);
          int diff= (l_height-(r_height));
          
          return diff;
      }
      
      //LL Rotation(Left Rotation)
    //when the imbalance factor is caused in the right child's right subtree 
      Node<T>* ll_rotate(Node<T>* &grand_parent_node){
          Node<T>* temp = grand_parent_node->m_right;
          grand_parent_node->m_right=temp->m_left;
          temp->m_left=grand_parent_node;
          return temp;
      }
      //RR Rotate 
      //when the imabalance is caused in the left childs left subtree
      Node<T>* rr_rotate(Node<T>* &grand_parent_node){
         Node<T>* temp= grand_parent_node->m_left;
         grand_parent_node->m_left=temp->m_right;
         temp->m_right=grand_parent_node;
         return temp;
      }
      //RL Rotate[Right left Rotation]
      //when the imbalance is in the right child's left subtree
     Node<T>* rl_rotate(Node<T>* &grand_parent_node){
         grand_parent_node->m_right=rr_rotate(grand_parent_node->m_right);
         return ll_rotate(grand_parent_node);
     }
      //Lr Rotate[Left right Rotation]
      //when the imbalance is in the left child's right subtree
     Node<T>* lr_rotate(Node<T>* &grand_parent_node){
         grand_parent_node->m_left=ll_rotate(grand_parent_node->m_left);
         return rr_rotate(grand_parent_node);
     }
    public:
      avl(){
          root=nullptr;
      }
      Node<T>* getroot(){
          return this->root;
      }
     //Height of the AVL tree
      int height(){
          return height(this->root);
      }
      

    //BalanceFactor of a node
      int balance_factor(){
        return balance_factor(this->root);
    }
      
    
 
    
     
     void add_node(T data,Node<T>* &node){
       if(this->root==nullptr){
         Node<T>* new_node= new Node<T>(data);
         this->root=new_node;
         
       }
       else{
         if(data<node->m_data){
           if(node->m_left!=nullptr){
             add_node(data,node->m_left);
            
           }else{
              Node<T>* new_node= new Node<T>(data);
              node->m_left=new_node;
              node=rebalance(node);
           }
         }
         if(data>node->m_data){
           if(node->m_right!=nullptr){
            add_node(data,node->m_right);
           }else{
              Node<T>* new_node= new Node<T>(data);
              node->m_right=new_node;
              node=rebalance(node);
           }
           
         }
       }
     }
     void add_node(T data){
       add_node(data,this->root);
     }
     
 

     void level_order_traversal(){
            if(this->root==nullptr){
                return;
            }
            std::queue<Node<T>* > q;
            q.push(this->root);
            
            while(!q.empty()){
                 Node<T>* current_node= q.front();
                 q.pop();
                 std::cout<<current_node->m_data<<" ";   
                 if(current_node->m_left!=nullptr){
                     q.push(current_node->m_left);
                 }
                 if(current_node->m_right!=nullptr){
                     q.push(current_node->m_right);
                 }
            }
        }
};
              return height(this->root);
          }
          int height(Node<T>* node){
              if(node==nullptr){return 0;}
              int l_height=height(node->m_left);
              int r_height=height(node->m_right);
            if(l_height>=r_height){return l_height+1;}
            else{return r_height+1;}
          }
    
        //BalanceFactor of a node
          int balance_factor(){
            return balance_factor(this->root);
        }
          int balance_factor(Node<T>* node){
            
              int l_height= height(node->m_left);
              int r_height= height(node->m_right);
              int diff= (l_height-(r_height));
              
              return diff;
          }
     
        //LL Rotation(Left Rotation)
        //when the imbalance factor is caused in the right child's right subtree 
          Node<T>* ll_rotate(Node<T>* grand_parent_node){
              Node<T>* temp = grand_parent_node->m_right;
              grand_parent_node->m_right=temp->m_left;
              temp->m_left=grand_parent_node;
              return temp;
          }
          //RR Rotate 
          //when the imabalance is caused in the left childs left subtree
          Node<T>* rr_rotate(Node<T>* grand_parent_node){
             Node<T>* temp= grand_parent_node->m_left;
             grand_parent_node->m_left=temp->m_right;
             temp->m_right=grand_parent_node;
             return temp;
          }
          //RL Rotate[Right left Rotation]
          //when the imbalance is in the right child's left subtree
         Node<T>* rl_rotate(Node<T>* grand_parent_node){
             grand_parent_node->m_right=rr_rotate(grand_parent_node->m_right);
             return ll_rotate(grand_parent_node);
         }
          //Lr Rotate[Left right Rotation]
          //when the imbalance is in the left child's right subtree
         Node<T>* lr_rotate(Node<T>* grand_parent_node){
             grand_parent_node->m_left=ll_rotate(grand_parent_node->m_left);
             return rr_rotate(grand_parent_node);
         }
         
         void add_node(T data,Node<T>* node){
           if(this->root==nullptr){
             Node<T>* new_node= new Node<T>(data);
             this->root=new_node;
             
           }
           else{
             if(data<node->m_data){
               if(node->m_left!=nullptr){
                 add_node(data,node->m_left);
                
               }else{
                  Node<T>* new_node= new Node<T>(data);
                  node->m_left=new_node;
                  node=rebalance(node);
               }
             }
             if(data>node->m_data){
               if(node->m_right!=nullptr){
                add_node(data,node->m_right);
               }else{
                  Node<T>* new_node= new Node<T>(data);
                  node->m_right=new_node;
                  node=rebalance(node);
               }
               
             }
           }
         }
         void add_node(T data){
           add_node(data,this->root);
         }
         
         Node<T>* rebalance(Node<T>* node){
           int bal_fact=balance_factor(node);
           if(bal_fact>1){
               if(balance_factor(node->m_left)>0){
                 node=ll_rotate(node);
               }else{
                 node=lr_rotate(node);
               }
           }
           if(bal_fact<-1){
              if(balance_factor(node->m_right)>0){
                 node=rl_rotate(node);
               }else{
                 node=rr_rotate(node);
               }
           }
           return node;
         }
    
         void level_order_traversal(){
                if(this->root==nullptr){
                    return;
                }
                std::queue<Node<T>* > q;
                q.push(this->root);
                
                while(!q.empty()){
                     Node<T>* current_node= q.front();
                     q.pop();
                     std::cout<<current_node->m_data<<" ";   
                     if(current_node->m_left!=nullptr){
                         q.push(current_node->m_left);
                     }
                     if(current_node->m_right!=nullptr){
                         q.push(current_node->m_right);
                     }
                }
            }
    };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...