0

So the problem I'm having is the insert method for an AVLtree. My avltree stores city objects, and I use the names of the cities to decide where they should go.

My City .cpp class:

 #include "City.h"
 #include <iostream>

  using namespace std;              


  City::City(string name, string country, double lat, double lon){
         this->name = name;
         this->country = country;
         this->latitude = lat;
         this->longtitude = lon;
             }

  double City::getLatOfCity(void){
         return this->latitude;
         }

  double City::getLonOfCity(void){
         return this->longtitude;
         }

  string City::getName(void){
         return this->name;
         }

  string City::getCountry(void){
         return this->country;
         }

The methods in my avltree .cpp file.

My rotate left method:

  Node* AVLtree::rotateLeft(Node* node){
       Node* tempParent= node->getParent();
       Node* tempNode = node->getChildL();
       node->setChildL(tempNode->getChildR());
       tempNode->setChildR(node);

       if(tempParent==0){tempNode->removeParent();this->rootNode=tempNode;}
       else{tempParent->setChildL(tempNode);
            //tempNode->updateParent(tempParent);
            }

       return tempNode;
       }

Rotate right method:

  Node* AVLtree::rotateRight(Node* node){ 
       Node* tempParent = node->getParent();
       if(tempParent!=0){cout<<"IHN";cout<<"temp parent: " << tempParent->getCity()->getName();}
       Node* tempNode = node->getChildR();
       node->setChildR(tempNode->getChildL());
       tempNode->setChildL(node);

       if(tempParent==0){tempNode->removeParent();this->rootNode=tempNode;}
       else{tempParent->setChildR(tempNode);}

       return tempNode;
       }

My first double right rotation method. This one doesn't work properly as the pointers I pass into the rotate methods are different when inside the method.

   /*  
  Node* AVLtree::rotateTwoRights(Node* node){
        node = rotateRight(node->getChildR());
        node = rotateRight(node->getParent());
        return node;
        }    */

I know this is very messy, but it seems to correctly rotate the nodes around.

  Node* AVLtree::rotateTwoRights(Node* node){
       Node* tempParent = node;
       Node* tempNode = node->getChildR();
       Node* tempTempNode = tempNode->getChildL();
       tempNode->setChildL(tempTempNode->getChildL());
       tempTempNode->setChildR(tempNode);
       tempParent->setChildR(tempTempNode);
       Node* tempTempParent = tempParent->getParent();
       tempTempParent->setChildR(tempParent->getChildL());
       tempParent->setChildL(tempTempParent);
       Node* newTempParent = tempParent->getParent();

       if(newTempParent==0){tempParent->removeParent();this->rootNode=tempParent;}
       else{newTempParent->setChildR(tempParent);} 

        return tempParent;
        }       

Same as my first rotate double right method, but for the left side. Same problems:

  Node* AVLtree::rotateTwoLefts(Node* node){
        node = rotateRight(node->getChildL());
        node = rotateLeft(node);
        return node;
        }

My insert method:

  Node* AVLtree::insertNode(Node* parent, Node* node, City *city, int side){
       if(node == 0){
               if(side==0){
                     node = parent->setChildL(new Node(city));
               }else if(side==1){
                     node = parent->setChildR(new Node(city));
               } 
       }else if(node->getCity()->getName().compare(city->getName())<0){ //Right case
             parent = node;
             node = insertNode(parent, node->getChildR(), city, 1);
             if(parent->getBalance()==2){
                   if(parent->getChildR()->getCity()->getName().compare(city->getName())<0){
                         node = rotateRight(parent);
                   }else{
                         node = rotateTwoRights(parent);
                   }                                
             } 
       }else if(node->getCity()->getName().compare(city->getName())>0){ //Left case
             parent = node;
             node = insertNode(parent, node->getChildL(), city, 0);
             if(parent->getBalance()==-2){
                   if(parent->getChildL()->getCity()->getName().compare(city->getName())>0){
                         node = rotateLeft(parent);
                   }else{
                         node = rotateTwoLefts(parent);
                   }
             }       
       }else{
             node=0;
       }
       return node;
       }

So the problem is when trying I try to insert a 'CA'.

So the tree would look like this:

   B
  / \
 A   C
      \
       D

and after inserting 'CA', it should follow these steps:

1)

   B
  / \
 A   C
      \
       D
      /
    CA   

2)

   B
  / \
 A   C
      \
       CA
        \
         D

3)

    C
   / \
  B   CA
 /     \
A       D

What the error is that when I run test on it, the root of the tree is still B. I believe it's due to parent, as it doesn't get updated when I rebalance the tree after the recursive call. However, when I assign parent to the return value of the method, then I can't even add 'C' to the tree.

I would be very grateful for any sort of help. I've spent a lot of time on this and really want to get this done.

I do apologize for the long post and messy code, and give my thanks in advance!

Student
  • 195
  • 1
  • 12

1 Answers1

0

Given that the node C is the first node where the depth of the left subtree (0) and the depth of the right subtree (2) differs by 2, I think there should be just a simple left rotation, yielding

  B
 / \
A   CA
   / \
  C   D

By the time the patch-up of the imbalance reaches B the tree is sufficiently balanced. I didn't look in detail at your code but your assumed result doesn't seem to be correct, i.e., there is a chance that the code actually is.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • Ah yes it should be like that. However, there still issues with the code :/ – Student Nov 23 '13 at 10:33
  • Just realised it shouldn't as it needs to follow the generic right-right rotation, where would result in my orginal post – Student Nov 23 '13 at 12:35