Python 如何实现AVL树旋转?
我已经编写了一个AVL树,我的旋转逻辑是正确的,但我仍然无法让它正常工作。对于根节点上的旋转,“我的旋转”工作正常,但如果旋转在树的更下方,则父节点不会指向已旋转到位的新节点,而是继续指向旋转前已就位的节点。我很确定问题出在我的insert方法上,但我不确定在发生旋转时如何让父节点指向新节点。我知道你可以添加一个父变量来解决这个问题,但我想知道是否有一种方法可以不用它Python 如何实现AVL树旋转?,python,recursion,avl-tree,Python,Recursion,Avl Tree,我已经编写了一个AVL树,我的旋转逻辑是正确的,但我仍然无法让它正常工作。对于根节点上的旋转,“我的旋转”工作正常,但如果旋转在树的更下方,则父节点不会指向已旋转到位的新节点,而是继续指向旋转前已就位的节点。我很确定问题出在我的insert方法上,但我不确定在发生旋转时如何让父节点指向新节点。我知道你可以添加一个父变量来解决这个问题,但我想知道是否有一种方法可以不用它 For example 10
For example
10 10 10
/ \ / \ instead of / \
8 12 Rotates to -> 8 12 6 12
/ \ \ / \ \
6 14 14 4 8 14
/ 4 and 6 are lost
4
在您的代码中,
insert
方法在插入完成并进行任何必要的旋转之后返回子树的新根。您的问题是,在一个子节点上递归调用insert
时,没有使用该返回值
if data < self.data:
if self.left is None:
self.left = MyAVL(data)
else:
self.left = self.left.insert(data) # update self.left here
elif data >= self.data:
if self.right is None:
self.right = MyAVL(data)
else:
self.right = self.right.insert(data) # and self.right here
如果数据=self.data:
如果self.right为无:
self.right=MyAVL(数据)
其他:
self.right=self.right.在此处插入(数据)#和self.right
需要说明的是,类MyAVL():
表示树的一个节点,而不是整个树,是吗?无论如何,您是否检查了树是否紧跟在insert
的实际插入部分之后,但在旋转之前?另外:请仔细考虑在开始旋转时哪个节点是self
。如果你有parent
指针,你会谈论如何解决这个问题,出于优雅的原因,你想避免使用这些指针;你能想出另一种方法来知道递归算法中的父项是什么吗?(提示:递归调用从何而来?该节点是否能提供帮助?我至少可以想出两种方法在调用之间传递必要的信息:in和out。)请提供预期的结果。显示中间结果与预期结果的偏差。我们应该能够将单个代码块粘贴到文件中,运行它,并重现您的问题。这也让我们可以在您的上下文中测试任何建议。您发布的代码定义了一个类,并在不做任何事情的情况下退出。我们期待这个问题的一个工作示例,包括跟踪内部操作的适当代码。此外,考虑以更有用的方式设计围绕旋转的接口。您只需检查节点以查看是否需要旋转,对吗?因此,与其将“找出节点是否不平衡”与“插入,然后在必要时平衡”进行分组,更合理的分组是“必要时平衡(其中“必要”需要检查)”与“插入”(这需要调用balance,因为我们应该在每次修改树时恢复平衡)”.@KarlKnechtel在本例中,当调用旋转时,self是节点8,旋转方法返回节点6。关于如何更新父节点的左子节点,我仍然是一片空白。
#This example works properly
test = AVL(10)
test= test.insert(12)
test = test.insert(8)
print(test.data) #outputs 8
print(test.left.data) #outputs 7
print(test.right.data) #outputs 10
#In this case the rotation occurs but the parent node does not update its left child to the new node and still points to 8
test2 = AVL(10)
test2 = test2.insert(12)
test2 = test2.insert(8)
test2 = test2.insert(14)
test2 = test2.insert(6)
test2 = test2.insert(4)
print(test2.data)#outputs 10
print(test2.left.data)#outputs 8 but should be 6
#4 and 6 can no longer be accessed because they are lost
if data < self.data:
if self.left is None:
self.left = MyAVL(data)
else:
self.left = self.left.insert(data) # update self.left here
elif data >= self.data:
if self.right is None:
self.right = MyAVL(data)
else:
self.right = self.right.insert(data) # and self.right here