【问题标题】:recursive class definition in pythonpython中的递归类定义
【发布时间】:2021-07-20 22:15:21
【问题描述】:

对不起,如果我的英语不好,我会说韩语作为母语。
我正在 Python 3 中实现二叉搜索树,但我无法实现我的目标。
这是代码:

class Node(object):

    def __init__(self, key=None, data=None):
        self.key = key
        self.data = data

class BinarySearchTree(object):
    keyfunc = None  # Will it be worse when using lambda x: x as default?
    
    def __init__(self, node=None):
        self.root = node
        self.left = None
        self.right = None
        # I don't want default to be NoneType, but don't know how for now.

    def add(self, key, data=None):
        node = Node(key, data)
        if self.root is None:
            self.root = node
            return
        parent = self.root.key
        if self.keyfunc is None:
            if key < parent:
                if self.left is None:
                    self.left = __class__(node)
                else:
                    self.left.add(key, data)
                        
            elif key > parent:
                if self.right is None:
                    self.right = __class__(node)
                else:
                    self.right.add(key, data)
        else:
            if keyfunc(key) < keyfunc(parent):
                if self.left is None:
                    self.left = __class__(node)
                else:
                    self.left.add(key, data)
            elif keyfunc(key) > keyfunc(parent):
                if self.right is None:
                    self.right = __class__(node)
                else:
                    self.right.add(key, data)
    def inorder(self):
        if self.root:
            if self.left:
                self.left.inorder()
            print(self.root.key, end=' ')
            if self.right:
                self.right.inorder()

if __name__ == '__main__':
    bst1 = BinarySearchTree()
    arr = [2,6,4,3,2,7,8,1,9,5]
    for key in arr:
        bst1.add(key)
    bst1.inorder()

无论如何它都可以,但我想要的是:

  • 即使根节点没有子节点,我希望bst1.left(或bst1.right)的类型始终为BinarySearchTree。
    这样,我可以允许空树与其他树保持一致,也可以在 add() 中删除重复的if self.left is None
  • 我不想在类定义之后手动执行bst1.left = BinarySearchTree(None),因为它需要应用于所有节点。

我试过self.left = BinarySearchTree(None)(当然它导致了不好的递归), 并尝试使用 __new__() 方法和元类,如其他 stackoverflow 问题中所回答的那样,但无法提出解决方案。
如果能得到帮助将不胜感激。

【问题讨论】:

  • 请参阅this Q&A 的主题。你应该会发现它很有帮助。如果您有后续问题,我随时为您提供帮助。
  • @谢谢你的问答很有趣。谢谢你介绍给我。

标签: python class recursion binary-tree recursive-datastructures


【解决方案1】:

考虑将NoneType 子树替换为具有None 根的空树对象。另外,为了回答您代码注释中的问题,我认为默认keyfunc = lambda x: x 是合理的,它可以进一步简化您的代码。

class BinarySearchTree:
    def __init__(self, node, keyfunc=lambda x: x):
        self.root = node
        self.keyfunc = keyfunc
        if node is not None:
            self.left = self.new_empty()
            self.right = self.new_empty()

    def new_empty(self):
        """Create a new empty child for this tree"""
        return BinarySearchTree(None, self.keyfunc)
    
    def add(self, key, data=None):
        node = Node(key, data)
        if self.root is None:
            self.root = node
            self.left = self.new_empty()
            self.right = self.new_empty()
        else:
            parent = self.root.key
            if self.keyfunc(key) < self.keyfunc(parent):
                self.left.add(key, data)
            elif self.keyfunc(key) > self.keyfunc(parent):
                self.right.add(key, data)

    def inorder(self):
        if self.root is not None:
            self.left.inorder()
            print(self.root.key, end=' ')
            self.right.inorder()

为了方便使用,您还可以选择添加如下定义:

def __bool__(self):
    return self.root is not None

这使您可以通过在inorder 方法中执行类似if self: 而不是if self.root is not None:if self.left: 之类的操作来简化测试以查看节点是否为空,以查看是否存在左子树而不是@ 987654330@.

【讨论】:

  • 条件if node is not None: 真的帮助了我。我很惊讶我无法提出这个条件。也许我的想法变得僵硬了。非常感谢!顺便说一句,我错了; keyfunc(key) 必须是 __class__.keyfunc(key)
  • @k9wan 啊,我忽略了 keyfunc = lambda x: x 行是在类定义中,而不是在模块范围内,这是可以工作的。我已经用接受keyfunc 作为参数的可能实现更新了答案,这就是我可能会这样做的方式。
猜你喜欢
  • 1970-01-01
  • 2019-05-19
  • 2021-07-10
  • 1970-01-01
  • 1970-01-01
  • 2017-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多