简体   繁体   English

所有节点的总和迭代 - 不递归 - 没有'左'和'右'

[英]Sum of all Nodes Iteratively - Not Recursively - Without 'left' and 'right'

I have this Binary Tree Structure: 我有这个二叉树结构:

# A Node is an object
# - value : Number
# - children : List of Nodes
class Node:
    def __init__(self, value, children):
        self.value = value
        self.children = children

I can easily sum the Nodes, recursively: 我可以很容易地递归地对节点求和:

def sumNodesRec(root):
    sumOfNodes = 0
    for child in root.children:
        sumOfNodes += sumNodesRec(child)
    return root.value + sumOfNodes 

Example Tree: 示例树:

exampleTree = Node(1,[Node(2,[]),Node(3,[Node(4,[Node(5,[]),Node(6,[Node(7,[])])])])])

sumNodesRec(exampleTree)

> 28

However, I'm having difficulty figuring out how to sum all the nodes iteratively. 但是,我很难弄清楚如何迭代地对所有节点求和。 Normally, with a binary tree that has 'left' and 'right' in the definition, I can find the sum. 通常,使用定义中具有“左”和“右”的二叉树,我可以找到总和。 But, this definition is tripping me up a bit when thinking about it iteratively. 但是,这个定义在迭代地思考它时会让我感到沮丧。

Any help or explanation would be great. 任何帮助或解释都会很棒。 I'm trying to make sure I'm not always doing things recursively, so I'm trying to practice creating normally recursive functions as iterative types, instead. 我试图确保我并不总是递归地做事情,所以我试图将正常的递归函数创建为迭代类型。

If we're talking iteration, this is a good use case for a queue . 如果我们正在讨论迭代,这是队列的一个很好的用例。

total = 0

queue = [exampleTree]
while queue: 
    v = queue.pop(0)
    queue.extend(v.children)
    total += v.value

print(total)
28

This is a common idiom. 这是一个常见的习语。 Iterative graph traversal algorithms also work in this manner. 迭代图遍历算法也以这种方式工作。

You can simulate stacks/queues using python's vanilla lists. 您可以使用python的vanilla列表模拟堆栈/队列。 Other (better) alternatives would be the collections.deque structure in the standard library. 其他(更好的)替代方案是标准库中的collections.deque结构。 I should explicitly mention that its enque/deque operations are more efficient than what you'd expect from a vanilla list. 我应该明确提到它的enque / deque操作比你对vanilla列表的期望更高效。

Iteratively you can create a list, stack, queue, or other structure that can hold the items you run through. 迭代地,您可以创建一个列表,堆栈,队列或其他可以容纳您运行的项目的结构。 Put the root into it. 把根放进去。 Start going through the list, take an element and add its children into the list also. 开始浏览列表,获取元素并将其子元素添加到列表中。 Add the value to the sum. 将值添加到总和。 Take next element and repeat. 采取下一个元素并重复。 This way there's no recursion but performance and memory usage may be worse. 这种方式没有递归,但性能和内存使用可能更糟。

In response to the first answer: 回答第一个答案:

def sumNodes(root):
    current = [root]
    nodeList = []
    while current:
        next_level = []
        for n in current:
            nodeList.append(n.value)
            next_level.extend(n.children)
        current = next_level
    return sum(nodeList)

Thank you! 谢谢! That explanation helped me think through it more clearly. 这种解释帮助我更清楚地思考它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM