返回None对象的值

时间:2016-02-04 15:53:20

标签: python algorithm oop methods avl-tree

我在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。我该如何解决?我试图尽可能减少此方法中重复的代码

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作为leftright关键字参数的默认值,self.left.heightself.right.height将始终有效(提供selfNode)的实例。

每次创建新节点时都不要忘记增加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()
相关问题