本周末我正在研究大学项目(数据结构),我必须用C ++编写AVL树代码。我认为先编码BST然后将其转换为AVL并不困难。可能我错了......我有两个类,类节点和类AVLTree,它是类节点的朋友。我设法根据BST的规则(我检查)进行插入和删除,并且我设法找到树的节点的平衡因子(这也有效)。然而,当我尝试简单的左旋转时,一切都发生了故障!这是我的代码(首先是.h文件):
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);
};
现在是AVLTree类的.cpp文件(仅限某些方法)
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
}
更新高度的方法:
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);
}
轮换试用代码(不起作用!)
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;
}
和Balancing方法:
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);
}
我也使用updateTreeHeights(这也经过了测试,并且在没有旋转的情况下运行良好)这里的方法效率不高,我知道,但我没有更好的主意!
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;
}
对不起,很长的帖子!这是我生命中第一次使用AVL树,更不用说编程了!希望你能帮忙!
答案 0 :(得分:0)
问题解决了!我用双转的左右指针搞砸了!