AVL树,c,旋转实现
code here:
http://pastebin.com/VAdc67bE
There's a problem in function rotacao_esquerda.
This is a rotation of a AVL tree.
How to fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有多种方法可以解决此问题:
printf
调试语句并运行它,检查输出。这些选项中只有两个会让您成为更好的开发人员,并且将来不太可能惹恼我们:-)
您首先应该尝试做的是缩小问题范围。所有问题报告(此处关于 SO 和现实世界)应包含:
任何不足都表明用户没有遵守约定。
好的,这就是您的函数,您似乎想要通过
no
(下面的A
)节点向右旋转。并且,根据您的评论:pai
= 父亲,dir
= 右侧,esq
= 左侧。所以你最终会得到这样的结果:
我看到一个直接可能的问题。您正在尝试更改该节点的父指针,以便它指向旋转后的节点
B
。但是您正在更改
no->pai->dir
,它是X
的右节点。如果树的结构如下,会发生什么?如果您尝试使用代码旋转该树的
A
节点,则会严重损害Y
子树。从粗略的桌面检查开始,我认为您可以从将:更改
为:开始,
这应该更改父级中的正确指针。请记住,我没有检查大量可能的树,只是检查了这一棵:
通过
DBEAFCGXY
的中序遍历,如果您通过A
向右旋转,通过我给出的代码更改,您将得到:看起来大约是正确的(按顺序
DBEAFGCXY
,与以前相同)。所以,最重要的是,尝试一下这个:
看看效果如何。
Diogo,我会给你留下一些代码来说明我的意思。查看下面的代码。它基本上创建一个虚拟结构并将其转储出来,然后在其上运行您的旋转例程。您可以从输出中看到生成的树是错误的。
然后,它重新创建原始树并运行固定旋转函数,产生我认为正确的结果。
如果您还有其他问题,请随意在调试过程中使用
dumpAvl
函数。它输出一个格式相对良好的树,其中一个节点后跟缩进的子节点(左侧为<
,右侧为>
)。当您运行它时,它会生成以下内容。您可以看到原始代码具有某些子树的多个副本,因为代码假设旋转点始终位于其父树的右侧。固定代码没有做出这样的假设。
There are a number of ways to fix this problem:
printf
debug statements throughout your code and run it, examining the output.Only two of those options will make you a better developer and less likely to annoy us in future :-)
What you should try to do first is to narrow the problem down. All problem reports (here on SO and in the real world) should contain:
Anything less is a user not keeping up their end of the bargain.
Okay, that's your function and it appears you want to rotate right through the
no
(A
below) node. And, as per your comment:pai
= father,dir
= right andesq
= left.so you end up with something like:
I see one immediate possible problem. You're trying to change the parent pointer of that node so that it points to the rotated node
B
.But you're changing
no->pai->dir
which is the right node ofX
. What happens if the tree is structured as follows?If you try to rotate through the
A
node of that tree with your code, you're going to seriously compromise theY
sub-tree.From a cursory desk-check, I think you can start by changing:
to:
which should change the correct pointer in the parent. Keep in mind I haven't checked a large number of possible trees, just this one:
with the in-order traversal of
DBEAFCGXY
, which, if you rotate right throughA
with the code change I gave, you get:which looks about right (inorder
DBEAFGCXY
, the same as before).So, bottom line, try this one:
and see how it goes.
Diogo, I'll leave you some code to play with to illustrate what I meant. Look over the following code. It basically creates a dummy structure and dumps it out then runs your rotate routine on it. You can see from the output that the resultant tree is wrong.
It then recreates the original tree and runs the fixed rotate function, producing what I believe to be the correct result.
Feel free to use the
dumpAvl
function in your debugging efforts if you have further problems. It outputs a relatively nicely formatted tree with a node followed by indented child nodes (<
for the left and>
for the right).When you run this, it produces the following. You can see the original code has multiple copies of some of the sub-trees due to the fact the code assumed the roration point would always be on the right side of its parent. The fixed code does not make that assumption.