簡體   English   中英

從遞歸二叉樹搜索返回數組

[英]Returning Array from Recursive Binary Tree Search

嗨,我制作了一個簡單的二叉樹並添加了一個前序遍歷方法。 在提出了一些想法之后,我陷入了尋找一種從數組中的traverse_pre()方法返回每個值的方法上。

class BST:
    def __init__(self, val):
        self.value = val
        self.left = None
        self.right = None

    def add_child(self, val):
        if self.value:
            if val < self.value:
                if self.left == None:
                    self.left = BST(val)
                else:
                    self.left.add_child(val)
            else:
                if val > self.value:
                    if self.right == None:
                        self.right = BST(val)
                    else:
                        self.right.add_child(val)
        else:
            self.value = val

    def traverse_pre(self):
        if self.left:
            self.left.traverse_pre()
        print(self.value)

        if self.right:
            self.right.traverse_pre()


Tree = BST(5)
Tree.add_child(10)
Tree.add_child(8)
Tree.add_child(2)
Tree.add_child(4)
Tree.add_child(7)

Tree.traverse_pre()

我將如何修改traverse_pre() function 以返回由節點值組成的數組。 這個過程是否有一個很好的例子讓我進一步理解這一點,我有點堅持如何在遞歸中將值附加到數組中。

這就是我的做法——所有分支都返回它們的子元素列表。

如果一個節點沒有子元素,它只返回它自己的值。 否則,它還包含來自子級的元素。

Extend 將子節點結果列表中的所有元素添加到父節點結果列表中。

class BST:
    def __init__(self, val):
        self.value = val
        self.left = None
        self.right = None

    def add_child(self, val):
        if self.value:
            if val < self.value:
                if self.left == None:
                    self.left = BST(val)
                else:
                    self.left.add_child(val)
            else:
                if val > self.value:
                    if self.right == None:
                        self.right = BST(val)
                    else:
                        self.right.add_child(val)
        else:
            self.value = val

    def traverse_pre(self):
        results = []

        if self.left:
            results.extend(self.left.traverse_pre())

        results.append(self.value)

        if self.right:
            results.extend(self.right.traverse_pre())

        return results


Tree = BST(5)
Tree.add_child(10)
Tree.add_child(8)
Tree.add_child(2)
Tree.add_child(4)
Tree.add_child(7)

print(Tree.traverse_pre())

您可以將數組用作全局變量,並且在 traverse_pre() function 中,您可以將 append 的值寫入該數組,而不是將其打印出來。

arr = []
class BST:
    def __init__(self, val):
        self.value = val
        self.left = None
        self.right = None

    def add_child(self, val):
        if self.value:
            if val < self.value:
                if self.left == None:
                    self.left = BST(val)
                else:
                    self.left.add_child(val)
            else:
                if val > self.value:
                    if self.right == None:
                        self.right = BST(val)
                    else:
                        self.right.add_child(val)
        else:
            self.value = val

    def traverse_pre(self):
        if self.left:
            self.left.traverse_pre()
        arr.append(self.value)

        if self.right:
            self.right.traverse_pre()


Tree = BST(5)
Tree.add_child(10)
Tree.add_child(8)
Tree.add_child(2)
Tree.add_child(4)
Tree.add_child(7)

Tree.traverse_pre() 
print(arr)

您可以使用yield而不是 return 來制作生成器。 當你調用它時,它可以變成一個列表。 這樣做的好處是不需要在每次調用時創建臨時內部列表:

class BST:
    def __init__(self, val):
        self.value = val
        self.left = None
        self.right = None

    def add_child(self, val):
        if self.value:
            if val < self.value:
                if self.left == None:
                    self.left = BST(val)
                else:
                    self.left.add_child(val)
            else:
                if val > self.value:
                    if self.right == None:
                        self.right = BST(val)
                    else:
                        self.right.add_child(val)
        else:
            self.value = val

    def traverse_pre(self):
        if self.left:
            yield from self.left.traverse_pre()
            
        yield self.value

        if self.right:
            yield from self.right.traverse_pre()


Tree = BST(5)
Tree.add_child(10)
Tree.add_child(8)
Tree.add_child(2)
Tree.add_child(4)
Tree.add_child(7)

list(Tree.traverse_pre())
# [2, 4, 5, 7, 8, 10]

我會這樣處理問題:

def traverse_pre(self):
    rslt = [self.value]
    if self.left:
        rslt.extend(self.left.traverse_pre())

    if self.right:
        rslt.extend(self.right.traverse_pre())

在 Python 中執行此操作的方法是不使用列表和.append ,它們會創建許多中間值。 而是使用yield你的樹可迭代並能夠直接使用內置 Python 函數的 yield -

class BST:
    # ...
    def preorder(self):
        # value
        yield self.value
        # left
        if self.left: yield from self.left.preorder()
        # right
        if self.right: yield from self.right.preorder()

我們可以簡單地重新排序這些行以提供不同的遍歷,例如inorder -

class BST:
    # ...
    def inorder(self):
        # left
        if self.left: yield from self.left.inorder()
        # value
        yield self.value
        # right
        if self.right: yield from self.right.inorder()

postorder -

class BST:
    # ...
    def postorder(self):
        # left
        if self.left: yield from self.left.postorder()
        # right
        if self.right: yield from self.right.postorder()
        # value
        yield self.value

要從生成器創建列表,只需使用list -

list(mytree.preorder())
# => [ ... ]

也就是說,您的代碼的 rest 仍有大量改進空間。 無需直接在您的BST class 中改變節點和糾結self上下文和遞歸方法。 使用薄class包裝器的功能方法將使您更容易擴展樹的功能。 有關此技術的更多信息,請參閱此相關問答

暫無
暫無

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

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