0

I'm working on a university project (Data structures) this weekend and I have to code an AVL tree in C++. I thought that it wouldn't be difficult to code a BST first and then convert it into an AVL. Probably I was wrong... I have two classes, class node and class AVLTree,which is friend of class node. I managed to do the insertions and deletions according to BST's rules (I checked) and also I managed to find the balance factor of its node of the tree (which also worked). However, when I tried the simple left rotations, everything went out of order! Here's my code (first the .h files):

class node
{
public:
    node();
private:
    int data;
    int heightL;
    int heightR;
    int balance;
    node* leftChild;
    node* rightChild;
    friend class AVLTree; //Only class AVLTree has now access to the private fields of     class node
};
class node;

class AVLTree
{
public:
    AVLTree();
    bool insertNode(int aData);
    node* searchNode(int key);
    bool deleteNode(int key);
    node* findMostLeft(node *aRoot);
    node* findMostRight(node *subtree);
    void display();
private:
    node *root;
    void inOrderTraversal(node* pointer);
    node* newNode(int aData);
    void updateHeightsInserting(int nodeCounter,int aData);
    void updateHeightsDeleting(int nodeCounter,int aData);
    void updateTreeHeights(node *ptr);
    int max(int a,int b);
    void balanceTree(node *current,node *previous,node *next);
    void slRotation(node* current,node *previous,node *next);
    void srRotation(node* current,node *previous,node *next);
    void dlRotation(node* current,node *previous,node *next);
    void drRotation(node* current,node *previous,node *next);

};

And now the .cpp file of class AVLTree (some methods only)

bool AVLTree::insertNode(int aData)
{
node *current,*next,*ptr;
bool isLeftChild;
int nodeCounter=0;
current=next=root;
ptr=newNode(aData);
if(ptr==NULL) //Couldn't allocate memory
{
    return false;
}
if(current==NULL) //Inserting the first node in our tree (root==NULL)
{
    root=ptr;
    return true; //Successful insertion of root
}
do
{
    if(aData<current->data) //If the node we want to insert has data smaller than the current node's data, then repeat the procedure for the left child of the current node
    {
        next=current->leftChild;
        isLeftChild=true;
        nodeCounter++;
    }
    else if(aData>current->data) //If the node we want to insert has data bigger than the current node's data, then repeat the procedure for the right child of the current node
    {
        next=current->rightChild;
        isLeftChild=false;
        nodeCounter++;
    }
    if(next==NULL)
    {
        if(isLeftChild)
        {
            current->leftChild=ptr;
        }
        else
        {
            current->rightChild=ptr;
        }
        updateHeightsInserting(nodeCounter,aData);
        return true;
    }
    current=next; //Repeat the procedure for the next node
}while(next!=NULL); //Repeat the procedure until there's no next node, meaning we enter the if(next==NULL) statement
}

The method for updating heights:

void AVLTree::updateHeightsInserting(int nodeCounter,int aData)
{
node *current,*next,*previous;
current=next=previous=root;
do
{
    if(aData<current->data)
    {
        if(current->heightL<nodeCounter)
        {
            current->heightL=nodeCounter;
        }
        next=current->leftChild;
        nodeCounter--;
    }
    else if(aData>current->data)
    {
        if(current->heightR<nodeCounter)
        {
            current->heightR=nodeCounter;
        }
        next=current->rightChild;
        nodeCounter--;
    }
    current->balance=current->heightR-current->heightL;
    if(abs(current->balance)>1)
    {
        if(abs(next->heightR-next->heightL)<1) //We use <1, because the hight of the next node hasn't been increased yet-If the next node isn't problematic it means the current node is
            balanceTree(current,previous,next);
    }
    previous=current;
    current=next;
}while(next->data!=aData);
}

A trial code for rotation (It doesn't work!)

void AVLTree::slRotation(node *current,node *previous,node *next)
{
if(current==root) //previous=current
{
   node *temp;
   root=next; //next=current->rightChild
   temp=next->leftChild;
   next->leftChild=current;
   current->rightChild=temp;
}
else
    previous->rightChild=next;
    current->rightChild=NULL;
    next->leftChild=current;
} 

And the Balancing method:

void AVLTree::balanceTree(node *current,node *previous,node *next)
{
if(current->balance>1) //if the tree is right heavy
    if(next->balance>0) //if the tree's right subtree is right heavy
        slRotation(current,previous,next); //perform Simple Left Rotation
    else //if the tree's right subtree is left heavy
        dlRotation(current,previous,next); //perform Double Left Rotation
else //if the tree is left heavy
    if(next->balance<0) //if the tree's left subtree is left heavy
        srRotation(current,previous,next); //perform Simple Right Roation
    else //if the tree's left subtree is right heavy
        drRotation(current,previous,next); //perform Double Right Rotation
updateTreeHeights(root);
}

I also use the updateTreeHeights (this is tested, too and works well without the rotations) method here that isn't efficient, I know, but I didn't have a better idea!

void AVLTree::updateTreeHeights(node *ptr)  //Visits the nodes by level recursively      (post-order traversal), so that it can calculate the balance of each node
{
if(ptr==NULL)
    return;
updateTreeHeights(ptr->leftChild);
updateTreeHeights(ptr->rightChild);
if(ptr->leftChild==NULL && ptr->rightChild==NULL)
{
    ptr->heightL=ptr->heightR=0;
}
else if(ptr->leftChild==NULL)
{
    ptr->heightR=max(ptr->rightChild->heightL,ptr->rightChild->heightR)+1;
    ptr->heightL=0;
}
else if(ptr->rightChild==NULL)
{
    ptr->heightL=max(ptr->leftChild->heightL,ptr->leftChild->heightR)+1;
    ptr->heightR=0;
}
else
{
    ptr->heightL=max(ptr->leftChild->heightL,ptr->leftChild->heightR)+1;
    ptr->heightR=max(ptr->rightChild->heightL,ptr->rightChild->heightR)+1;
}
ptr->balance=ptr->heightR-ptr->heightL;
}

Sorry for the long post! It's the first time in my life I use an AVL tree, let alone programming it! Hope you can help!

syfantid
  • 366
  • 5
  • 20

1 Answers1

0

Problem solved! I messed up with the right and left pointers in double rotations!

syfantid
  • 366
  • 5
  • 20