簡體   English   中英

python 中的遞歸 class 定義

[英]recursive class definition in python

對不起,如果我的英語不好,我會說韓語作為母語。
我正在 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。
    這樣,我可以允許 null 樹與其他樹保持一致,並且if self.left is None ,我也可以刪除重復。
  • 我不想在 class 定義之后手動執行bst1.left = BinarySearchTree(None) ,因為它需要應用於所有節點。

我嘗試self.left = BinarySearchTree(None) (當然它導致了錯誤的遞歸),並嘗試使用__new__()方法和 Metaclasses,如其他 stackoverflow 問題中所回答的那樣,但無法提出解決方案。
如果我能得到幫助將不勝感激。

考慮將NoneType子樹替換為具有None根的空樹 object。 另外,要回答代碼注釋中的問題,我認為默認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

這使您可以通過執行類似if self:而不是if self.root is not None:inorder方法中或if self.left:來查看是否存在左子樹來簡化測試以查看節點是否為空if self.left.root is not None:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM