AVL树的插入方法?
我将向您发布使用我开发的 AVL 树 的代码。下面列出了插入的方法avlinsert
方法。我在纸上开发了这段代码,尚未经过测试,但我希望这会起作用。我想讨论的主要问题是节点的平衡因素首先看代码。这样我想问的问题就会变得清晰。所以这里是代码:
treeNode* avlinsert(treeNode* tree, int info)
{
treeNode* newNode=new treeNode;
newNode->setinfo(info);
newNode->setbalance(0);
treeNode* p,*q;
bool duplicate=false;
p=q=tree;
stack s; //I have made this stack already and now I am using it here.
//Now the the while loop block will check for duplicate nodes, this block prevents the duplicate insertion.
while (q!=NULL)
{
p=q;
if (info < p -> getinfo())
q=p->getleft();
else if (info>p->getinfo())
q=p->getright();
else
{
duplicate=true;
cout<<"Trying to insert duplicate";
break;
}
}//while loop ended.
//Now checking for duplicates.
if (duplicate)
return tree;
p=q=tree;
//Now below is the main block of while loop which calculates the balance factors of nodes and helps in inserting nodes at proper positions.
while (q!=NULL)
{
p=q;
if (info < p -> getinfo())
{
p->setbalance(p -> getbalance()+1);
s.push(p);//pushing into stack
q=p->getleft();
}
else if (info > p -> getinfo())
{
p->setbalance(p->getbalance()-1);
q=p->getright();
}
}//while loop ended
//Now the below code block will actually inserts nodes.
if (info < p -> getinfo())
p->setleft(newNode);
else if (info > p -> getinfo())
p->setright(newNode);
//After this insertion we need to check the balance factor of the nodesand perform the approprite rotations.
while (!s.isempty())
{
treeNode node;
node=s.pop();
int balance;
balance=node.getbalance();
if (balance==2)
{
s.Makeempty(); // We have found the node whoes balance factor is violating avl condition so we don't need other nodes in the stack, therefor we are making stack empty.
treeNode* k1,*k3;
k1=&node; //This is the node whoes balance factor is violating AVL condition.
k3=&(k1 -> getleft()); //Root of the left subtree of k1.
//Identifying the cases of insertion
if (info < k3 -> getinfo()) //This is the case of insertion in left subtree of left child of k1 here we need single right rotation.
root=Rightrotation(k1); //Here root is the private data member.
//Next case is the insertion in right subtree of left child of k1.
if (info > k3 ->getinfo())
root=LeftRightrotation(k1);
}//end of if statement.
}//while loop ended
这不是完整的代码,但它足以向您展示我正在尝试做的事情。您在这段代码中看到,我在插入期间设置节点的平衡因子(第二个 while 循环块)。好的,这很好。但在插入之后我需要执行旋转。我也有旋转代码,但主要问题是当节点旋转时,我需要重置旋转代码中节点的平衡因子。这是我的问题。我怎样才能做到呢?代码片段是什么?
I am posting you the code for using an AVL tree that I developed. The method for insert, avlinsert
method is listed below. I developed this code on paper and it's not tested but I hope this will work. The main problem I want to discuss is the balance factor of the nodes first look at the code. In this way the idea will become clear what I am trying to ask. So here is code:
treeNode* avlinsert(treeNode* tree, int info)
{
treeNode* newNode=new treeNode;
newNode->setinfo(info);
newNode->setbalance(0);
treeNode* p,*q;
bool duplicate=false;
p=q=tree;
stack s; //I have made this stack already and now I am using it here.
//Now the the while loop block will check for duplicate nodes, this block prevents the duplicate insertion.
while (q!=NULL)
{
p=q;
if (info < p -> getinfo())
q=p->getleft();
else if (info>p->getinfo())
q=p->getright();
else
{
duplicate=true;
cout<<"Trying to insert duplicate";
break;
}
}//while loop ended.
//Now checking for duplicates.
if (duplicate)
return tree;
p=q=tree;
//Now below is the main block of while loop which calculates the balance factors of nodes and helps in inserting nodes at proper positions.
while (q!=NULL)
{
p=q;
if (info < p -> getinfo())
{
p->setbalance(p -> getbalance()+1);
s.push(p);//pushing into stack
q=p->getleft();
}
else if (info > p -> getinfo())
{
p->setbalance(p->getbalance()-1);
q=p->getright();
}
}//while loop ended
//Now the below code block will actually inserts nodes.
if (info < p -> getinfo())
p->setleft(newNode);
else if (info > p -> getinfo())
p->setright(newNode);
//After this insertion we need to check the balance factor of the nodesand perform the approprite rotations.
while (!s.isempty())
{
treeNode node;
node=s.pop();
int balance;
balance=node.getbalance();
if (balance==2)
{
s.Makeempty(); // We have found the node whoes balance factor is violating avl condition so we don't need other nodes in the stack, therefor we are making stack empty.
treeNode* k1,*k3;
k1=&node; //This is the node whoes balance factor is violating AVL condition.
k3=&(k1 -> getleft()); //Root of the left subtree of k1.
//Identifying the cases of insertion
if (info < k3 -> getinfo()) //This is the case of insertion in left subtree of left child of k1 here we need single right rotation.
root=Rightrotation(k1); //Here root is the private data member.
//Next case is the insertion in right subtree of left child of k1.
if (info > k3 ->getinfo())
root=LeftRightrotation(k1);
}//end of if statement.
}//while loop ended
This is not the whole code but it's enough to show you what I am trying to do. You have seen in this code that I am setting the balance factor of nodes during insertion (second while loop block). OK, this is fine. But after this insertion I need to perform rotations. I have the code of rotations as well but the main problem is when the nodes are rotated then I need to reset the balance factors of the nodes in the rotation's code. This is the problem with me. How I can do it? And what would a code snippet be?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
“...我需要在轮换代码中重置节点的平衡系数。”
如果您想在旋转代码中添加一些内容,那么也许您还应该发布旋转函数的代码以获得帮助。
否则,如果您只想在旋转后更新每个节点的平衡因子,那么这个递归函数可能会帮助您(只需调用它并传递树的根节点):
另外,我在您的代码中发现了一些错误,但是我'我很确定当您尝试运行程序时会找到它们。需要记住的一些事情:
我不确定堆栈的实现是如何工作的,但我看到您将一个指针推入堆栈,然后弹出一个对象:
s.push(p);
treenode node = s.pop();
仅当您遍历 AVL 树的左子树时(而不是向右遍历时)才将节点推入堆栈。这是为什么?
当你将newNode插入到树中时,记得将newNode的左右子节点设置为NULL(也许你已经在构造函数中这样做了,但我不确定)。
通常,在AVL树中,当一个节点的左子树高于右子树时,则该节点的平衡因子为负。您可能想在代码中更改它。如果你想保持这样,你就必须改变我的递归函数。
最后但并非最不重要的一点是,您检查平衡因子是否等于 2(如果您的树需要旋转)。请记住,平衡因子也可以取负值(如果左子树高于右子树)。
祝大家新年快乐:-)
"...I need to reset the balance factors of the nodes in the rotation's code."
If you want to add something inside the rotation's code, then maybe you should also post the code of the rotation functions in order to get help.
Otherwise, if you just want to update each node's balance factors after the rotation, then this recursive function might help you (just call it and pass the root node of your tree):
Also, I spotted some errors in your code, but I'm pretty sure you'll find them when you'll try to run your program. Some things to bear in mind:
I'm not sure how your implementation of stack works, but I see that you push into the stack a pointer and then you pop an object:
s.push(p);
treenode node = s.pop();
You push nodes into the stack only when you traverse the left subtree of your AVL tree, and not when you go right. Why is that?
When you insert the newNode into the tree, remember to set newNode's left and right children to NULL (maybe you already do that in your constructor, but I'm not sure).
Usually, in AVL trees, when the left subtree is higher than the right subtree of a node, then the balance factor of that node is negative. You might want to change that in your code. If you want to leave it like that, you 'll have to change my recursive function.
Last but not least, you check to see if the balance factor is equal to 2 (if your tree needs rotation). Remember that the balance factor can take negative values as well (if the left subtree is higher than the right subtree).
Happy new year to everyone :-)