【问题标题】:C++ AVLtree insertion methodC++ AVLtree插入方法
【发布时间】:2013-12-08 00:03:48
【问题描述】:

所以我遇到的问题是 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;
         }

我的 avltree .cpp 文件中的方法。

我的向左旋转方法:

  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”添加到树中。

如果能提供任何帮助,我将不胜感激。我在这方面花了很多时间,我真的很想完成这项工作。

对于冗长的帖子和混乱的代码,我深表歉意,并提前致谢!

【问题讨论】:

    标签: c++ pointers rotation insertion avl-tree


    【解决方案1】:

    鉴于节点C是第一个左子树深度(0)和右子树深度(2)相差2的节点,我认为应该只是一个简单的左旋转,产生

      B
     / \
    A   CA
       / \
      C   D
    

    当不平衡的修补达到B 时,树已充分平衡。我没有详细查看您的代码,但您假设的结果似乎不正确,即代码实际上有可能是正确的。

    【讨论】:

    • 啊,应该是这样的。但是,代码仍然存在问题:/
    • 刚刚意识到它不应该,因为它需要遵循通用的左右旋转,这会导致我的原始帖子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 2020-08-22
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多