我在AVL树实现中添加了方法。
class Node:
def __init__(self, data, left = None, right = None, height = -1):
self.data = data
self.left = left
self.right = right
self.height = height
def addNode(self, data):
if self.data > data:
'''Adding to left subtree'''
if self.left is None:
self.left = Node(data)
else:
self.left.addNode(data)
if ( abs(self.right.height - self.left.height) == 2):
''' Then we need to balance a subtree'''
print("Rebalancing after inserting", data)
if (data < self.left.data):
self.rotateLeft()
else:
self.doubleRotateLeft()
elif self.data < data:
'''Adding to right subtree'''
if self.right is None:
self.right = Node(data)
else:
self.right.addNode(data)
if ( abs(self.right.height - self.left.height) == 2):
''' Then we need to balance a subtree'''
print("Rebalancing after inserting", data)
if (data < self.right.data):
self.rotateRight()
else:
self.doubleRotateRight()
但是当我尝试做的时候
self.right.height
并且self没有正确的对象然后它不会返回高度,即使默认值为-1。我该如何解决?我试图尽可能减少此方法中重复的代码
答案 0 :(得分:1)
如果self.right
设置为None
,则您无法使用self.right.height
,不会。如果该表达式必须有效,请不要使用None
。请改为使用定义该属性的标记。
sentinel可以只是一个没有值且没有子节点的自定义类。你可以像None
:
class Sentinel(object):
value = left = right = None
height = -1
sentinel = Sentinel()
class Node:
def __init__(self, data, left=sentinel, right=sentinel, height=-1):
# ...
然后在代码中测试is sentinel
而不是is None
。通过使用sentinel
作为left
和right
关键字参数的默认值,self.left.height
和self.right.height
将始终有效(提供self
是Node
)的实例。
每次创建新节点时都不要忘记增加height
。
您可以使用本地参考资料稍微简化addNone()
方法:
def addNode(self, data):
if self.data == data: return
left = self.data > data
testnode = self.left if left else self.right
if testnode is sentinel:
node = Node(data)
setattr(self, 'left' if left else 'right', node)
else:
testnode.addNode(data)
if abs(self.right.height - self.left.height) == 2:
if data < testnode.data:
rotation = self.rotateLeft if left else self.rotateRight
else:
rotation = self.doubleRotateLeft if left else self.doubleRotateRight
rotation()