Метод вставки дерева C ++ AVL

0

Поэтому проблема, с которой я столкнулась, - это метод вставки для AVLtree. Мой avltree хранит городские объекты, и я использую названия городов, чтобы решить, куда они должны идти.

Мой город.cpp класс:

 #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;
         }

Методы в моем файле.cpp avltree.

Мой метод поворота слева:

  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;
       }

Поверните правый метод:

  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;
       }

Мой первый метод двойного правого вращения. Это не работает должным образом, поскольку указатели, которые я передаю в методы поворота, различны, когда внутри метода.

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

Я знаю, что это очень грязно, но кажется, что он правильно вращает узлы вокруг.

  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;
        }       

То же, что и мой первый метод с двойным правым вращением, но для левой стороны. Те же проблемы:

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

Мой метод вставки:

  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;
       }

Таким образом, проблема заключается в попытке попытаться вставить "CA".

Таким образом, дерево будет выглядеть так:

   B
  / \
 A   C
      \
       D

и после вставки "CA" он должен выполнить следующие шаги:

1)

   B
  / \
 A   C
      \
       D
      /
    CA   

2)

   B
  / \
 A   C
      \
       CA
        \
         D

3)

    C
   / \
  B   CA
 /     \
A       D

Ошибка в том, что при запуске теста на нем корень дерева по-прежнему остается B. Я считаю, что это связано с parent, поскольку он не обновляется, когда я ребалансирую дерево после рекурсивного вызова. Однако, когда я назначаю parent возвращаемому значению метода, я даже не могу добавить 'C' к дереву.

Я был бы очень благодарен за любую помощь. Я потратил много времени на это и действительно хочу сделать это.

Я извиняюсь за длинный пост и грязный код и заранее благодарю вас!

Теги:
pointers
rotation
avl-tree
insertion

1 ответ

0

Учитывая, что узел C является первым узлом, где глубина левого поддерева (0) и глубина правого поддерева (2) отличается на 2, я думаю, что должно быть просто простое левое вращение,

  B
 / \
A   CA
   / \
  C   D

К тому времени, когда исправление дисбаланса достигнет B дерево достаточно сбалансировано. Я не стал подробно смотреть на ваш код, но ваш предполагаемый результат не кажется правильным, т.е. Есть вероятность, что код на самом деле.

  • 0
    Ах да, так и должно быть. Тем не менее, есть все еще проблемы с кодом: /
  • 0
    Просто понял, что это не так, как нужно, чтобы следовать обычному повороту вправо-вправо, в результате чего мой оригинальный пост

Ещё вопросы

Сообщество Overcoder
Наверх
Меню