【问题标题】:Python How to implement a recursive method of Binary Search Tree that returns a list that contains every node in this treePython如何实现二叉搜索树的递归方法,该方法返回一个包含该树中每个节点的列表
【发布时间】:2016-11-10 05:55:52
【问题描述】:

如果有tree example

返回表单:[(depth 1, [ all items in depth 1]), (depth 2, [ all items in depth2]) ]

这个方法printitem_all_layers()应该返回[ (1,[2] ) , ( 2,[1,3] ) ]

虽然我写了一个递归方法items_at_depth(self, d),它可以返回深度为d的树的项目列表,所以我知道使用items_at_depth(self, d)实现方法printitem_all_layers()很容易。但它的效率要低得多,所以我在想如何让printitem_all_layers() 自己递归,这样我就不需要其他递归方法了

class BinarySearchTree:
    def __init__(self, root):
                if root is None:
        self._root = None
        self._left = None
        self._right = None
    else:
        self._root = root
        self._left = BinarySearchTree(None)
        self._right = BinarySearchTree(None)

    def is_empty(self):
        return self._root is None

    def items_at_depth(self, d):

    """Return a sorted list of all items in this BST at depth <d>.

    Precondition: d >= 1.
    @type self: BinarySearchTree
    @type d: int
    @rtype: list
    """
    lst = []
    if d - 1 >= 1 and not self._left.is_empty():
        lst.extend(self._left.items_at_depth(d-1))
    if d == 1 and not self.is_empty():
        lst.append(self._root)
    if d - 1 >= 1 and not self._right.is_empty():
        lst.extend(self._right.items_at_depth(d-1))

    return lst

下面是我之前所做的,没有递归

    def printitem_all_layers(self):
    """Return a list of items in the tree, separated by level.

    @type self: BinarySearchTree
    @rtype: list[(int, list)]

    """
    lst = list()
    for each in range(1, self.height()+1):
        lst.append(tuple((each, self.items_at_depth(each))))
    return lst

【问题讨论】:

  • 您能否展示您编写的函数的代码,以便我们为您指明正确的方向?
  • 我认为你没有听说过breadth-first search。您可以在 Google 上搜索迭代而不是递归的相同实现。诀窍是使用队列,并用你所拥有的层深度标记你看到的每个元素。
  • 我更新了问题

标签: python python-3.x recursion tree


【解决方案1】:

以下是广度优先搜索的迭代版本,它适合您的问题,在堆栈空间使用方面更高效,并保证与纯递归实现类似的运行时间:

from collections import defaultdict

class Node:

    def __init__(self, value, descendants=[]):
        ''' A class to represent the node of a tree '''

        self.value = value

        # note that descendants should be iterable for 
        # our breadth-first search logic to take place
        # - otherwise it doesn't really matter what type 
        # it is.
        self.descendants = descendants

    def __repr__(self):
        return str(self.value)

def print_layer(root):

    # private queue consists of elements of the form (depth, Node)
    private_queue = [(0,root)]

    # instantiate a dictionary where every new value is always initialized 
    # to a list 
    depth_to_nodes_map = defaultdict(list)

    # keep adding descendants of each node in your tree to your queue
    # in order of visiting them, and also store each popped value in
    # your defaultdict, mapping depth to a list of nodes seen. Look up
    # breadth-first search if you don't understand why I'm waiting for
    # the queue to exhaust itself.

    while private_queue != []:

        # get the first element of private_queue
        current_depth, current_node = private_queue.pop(0)

        depth_to_nodes_map[current_depth].append(current_node)

        for child in current_node.descendants:
            private_queue.append((current_depth + 1, child))

    return depth_to_nodes_map.items()

一个引用树的例子:

2 -> {1 -> {0}, 3}

我们将按如下方式创建这棵树:

root = Node(2, [Node(1, [Node(0)]), Node(3)])

并调用print_layers(root) 给出:

[(0, [2]), (1, [1, 3]), (2, [0])]

这正是你想要的。

【讨论】:

  • 这很好!但是我的 BST 类没有使用您提出的类 Node,我还更新了我放置代码的问题,以便您查看。除了使用呼吸优先搜索之外,您能否帮我使用递归 print_layer(self),因为我之前从未听说过 XD
  • 有几件事:a)请发布您的完整代码,而不仅仅是您想要优化的方法,这样我可以提供更好的帮助(我不知道您的 BST 现在实现了什么)b)请澄清你所说的“高效”是什么意思——在没有尾调用优化的 Python 等语言中,递归函数总是比迭代版本占用更多的内存——并且 c)广度优先搜索和深度优先搜索是最简单和最常用的算法搜索和遍历树木 - 值得您花时间学习。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-13
  • 2018-10-30
  • 2013-06-19
  • 2023-03-29
相关资源
最近更新 更多