簡體   English   中英

Python 遞歸樹

[英]Python Recursive Tree

我是編程新手,我想定義一個 function 允許我在非二叉樹中找到一個元素,並在列表中跟蹤該元素的所有父元素。 這棵樹被編碼為一個元組,其中索引 0 是父節點,索引 1 是其子節點的列表。 該列表包含每個子項的元組,其組成方式與以前相同(索引 0 是父項,索引 1 是子項)。

例子:

tree_data = (
    'Alan', [
        (
            'Bob', [
                ('Chris', []),
                (
                    'Debbie', [
                        ('Cindy', [])
                    ]
                )
            ]
        ),
        (
            'Eric', [
                ('Dan', []),
                (
                    'Fanny', [
                        ('George', [])
                    ]
                )
            ]
        ),
        ('Hannah', [])
    ]
)

查找 'George' 將返回以下內容: ['George', 'Eric'. 'Alan'] ['George', 'Eric'. 'Alan']

到目前為止,我有以下內容:我已經成功地只有 append 元素和直接父級,但沒有進一步。

此外,如果我向 function 添加返回語句,結果為 None。 希望能提供一點幫助。

lst = [] 
def list_parentals(tree, element):   
    if tree[0] == element: 
        lst.append(element)            
    else:
        for child in tree[1]:
            list_parentals(child, element)
            if child[0] == element:
                lst.append(tree[0])

您可以像 go 一樣構建它,而不是在外部保留列表。

def list_parentals(tree, element, parents):
    this, children = tree
    new_parents = [this] + parents
    if this == element:
        return new_parents
    else:
        for child in children:
            x = list_parentals(child, element, new_parents)
            # If x is not None, return it
            if x:
                return x

list_parentals(t, 'George', [])
# ['George', 'Fanny', 'Eric', 'Alan']

對於“我的遞歸 function 返回 None”,這是一個非常非常經典的問題。 在搜索這些詞時,您會找到數百個關於此的詳細答案。

但簡而言之,遞歸 function 必須始終返回某些內容,而不僅僅是在找到某些內容時返回。 通常,在這樣的示例中,您必須在找到正確的葉子時返回結果。 但是,如果您不希望該結果丟失,那么,當您調用找到葉子的遞歸時,您還必須返回一些東西。 當你調用那個調用那個找到葉子的遞歸的遞歸時。

請記住,最終結果是第一次調用list_parentals的返回值。 如果第一個調用沒有返回任何東西,那么,某些遞歸子調用是否返回並不重要。

其次,構建這樣一條路徑的方式恰恰是利用了遞歸。 當您找到匹配的葉子時,嘗試在全局變量中創建一個列表並不容易。 當遞歸的全部目的就是為你做這件事時,你可能最終會嘗試用迭代算法來計算它。

這是一個有效的遞歸方法(我試圖讓它盡可能接近你自己的代碼)

tree=('Alan', [('Bob', [('Chris', []), ('Debbie', [('Cindy', [])])]), ('Eric', [('Dan', []), ('Fanny', [('George', [])])]), ('Hannah', [])])

def list_parentals(tree, element):
    if tree[0] == element:
        return [element]
    else:
        for child in tree[1]:
            sub=list_parentals(child, element)
            if sub:
                return [tree[0]] + sub
        return []

r=list_parentals(tree, 'George')
print(f"{r=}")

其邏輯是list_parental(tree, 'George')返回樹中到葉子 'George' 的路徑,如果沒有找到這樣的葉子,則返回[] (或 None 或 False,無關緊要)。 所以(暫時將其視為數學表達式,而不是代碼), list_parental(('Alan', [('Bob', [('Chris', []), ('Debbie', [('Cindy', [])])]), ('Eric', [('Dan', []), ('Fanny', [('George', [])])]), ('Hannah', [])]), 'George')只是Alan加上 `list_parental(('Eric', [('Dan', [])), ('Fanny', [('George', [])])]) , '喬治')。

``list_parental(('Eric', [('Dan', []), ('Fanny', [('George', [])])]), 'George') is just Eric plus list_parental(('范妮', [('喬治', [])]), '喬治')`。

list_parental(('Fanny', [('George', [])]), 'George')只是Fanny加上list_parental(('George', []), 'George')

list_parental(('George', []), 'George')就是George

為了保持一致,所有返回都必須是列表。

因此我的代碼。

list_parental(tree, leafName) is [leafName]是樹匹配leafName的根。

否則list_parental(tree, leafName)[tree[0]] + list_parental(child, leafName)如果其中一個孩子包含 leafName,即如果list_parental(child, leafName)不為空。

暫無
暫無

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

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