在递归二叉树函数中返回元组时遇到问题

Posted

技术标签:

【中文标题】在递归二叉树函数中返回元组时遇到问题【英文标题】:Trouble returning tuple in a recursive binary tree function 【发布时间】:2022-01-07 16:14:00 【问题描述】:

我正在编写一个函数,它递归地找到二叉树中的最小值和最大值并返回一个元组 (min, max)。我的代码为我的测试用例返回了正确的最小值和最大值,但分别返回。任何关于如何让它返回元组的建议都值得赞赏! (请注意,我不允许使用为我遍历树的 LinkedBinaryTree 函数,但我在我的代码下附加了我当前正在使用的类)

我的代码

from LinkedBinaryTree import LinkedBinaryTree


def min_and_max(bin_tree):

    if bin_tree is None:
        raise Exception("Tree is empty")

    def subtree_min_and_max(root):
        minval = root.data
        maxval = root.data
        if (root.left is None and root.right is None):
            temp = (minval, maxval)
            return temp
        elif (root.left is None):
            ltemp = subtree_min_and_max(root.right)
            if (ltemp[0] < minval):
                minval= ltemp[0]
            if (ltemp[1] > maxval):
                maxval = ltemp[1]
            temp = (minval, maxval)
            return temp
        elif (root.right is None):
            subtree_min_and_max(root.left)
            rtemp = subtree_min_and_max(root.right)
            if (rtemp[0] < minval):
                minval = rtemp[0]
            if (rtemp[1] > maxval):
                maxval = rtemp[1]
            temp = (minval, maxval)
            return temp
        else:
            ltemp = subtree_min_and_max(root.left)
            rtemp = subtree_min_and_max(root.right)
            print((min(root.data, ltemp[0], rtemp[0])))
            print(max(root.data, ltemp[1], rtemp[1]))
            temp = (min(root.data, ltemp[0], rtemp[0]), max(root.data, ltemp[1], rtemp[1]))
            return temp

    return subtree_min_and_max(bin_tree.root)

LinkedBinaryTree 类

from ArrayQueue import ArrayQueue

class LinkedBinaryTree:

    class Node:
        def __init__(self, data, left=None, right=None):
            self.data = data
            self.parent = None
            self.left = left
            if (self.left is not None):
                self.left.parent = self
            self.right = right
            if (self.right is not None):
                self.right.parent = self

    def __init__(self, root=None):
        self.root = root
        self.size = self.count_nodes()

    def __len__(self):
        return self.size

    def is_empty(self):
        return len(self) == 0


    def count_nodes(self):
        def subtree_count(root):
            if (root is None):
                return 0
            else:
                left_count = subtree_count(root.left)
                right_count = subtree_count(root.right)
                return 1 + left_count + right_count

        return subtree_count(self.root)


    def sum(self):
        def subtree_sum(root):
            if (root is None):
                return 0
            else:
                left_sum = subtree_sum(root.left)
                right_sum = subtree_sum(root.right)
                return root.data + left_sum + right_sum

        return subtree_sum(self.root)


    def height(self):
        def subtree_height(root):
            if (root.left is None and root.right is None):
                return 0
            elif (root.left is None):
                return 1 + subtree_height(root.right)
            elif (root.right is None):
                return 1 + subtree_height(root.left)
            else:
                left_height = subtree_height(root.left)
                right_height = subtree_height(root.right)
                return 1 + max(left_height, right_height)

        if(self.is_empty()):
            raise Exception("Tree is empty")
        return subtree_height(self.root)


    def preorder(self):
        def subtree_preorder(root):
            if (root is None):
                pass
            else:
                yield root
                yield from subtree_preorder(root.left)
                yield from subtree_preorder(root.right)

        yield from subtree_preorder(self.root)


    def postorder(self):
        def subtree_postorder(root):
            if (root is None):
                pass
            else:
                yield from subtree_postorder(root.left)
                yield from subtree_postorder(root.right)
                yield root

        yield from subtree_postorder(self.root)


    def inorder(self):
        def subtree_inorder(root):
            if (root is None):
                pass
            else:
                yield from subtree_inorder(root.left)
                yield root
                yield from subtree_inorder(root.right)

        yield from subtree_inorder(self.root)


    def breadth_first(self):
        if (self.is_empty()):
            return
        line = ArrayQueue()
        line.enqueue(self.root)
        while (line.is_empty() == False):
            curr_node = line.dequeue()
            yield curr_node
            if (curr_node.left is not None):
                line.enqueue(curr_node.left)
            if (curr_node.right is not None):
                line.enqueue(curr_node.right)

    def __iter__(self):
        for node in self.breadth_first():
            yield node.data

我的测试代码

root = LinkedBinaryTree.Node(3)
T = LinkedBinaryTree(root)
a = LinkedBinaryTree.Node(2)
a.parent = root
root.left = a
b = LinkedBinaryTree.Node(7)
b.parent = root
root.right = b
c = LinkedBinaryTree.Node(9)
c.parent = a
a.left = c
d = LinkedBinaryTree.Node(5)
d.parent = c
c.left = d
e = LinkedBinaryTree.Node(1)
e.parent = c
c.right = e
f = LinkedBinaryTree.Node(8)
f.parent = b
b.left = f
g = LinkedBinaryTree.Node(4)
g.parent = b
b.right = g
print(min_and_max(T))

测试代码生成一棵看起来像这样的树

【问题讨论】:

【参考方案1】:

subtree_min_and_max,当root.right is None的情况下,你的代码做:

subtree_min_and_max(root.left)
rtemp = subtree_min_and_max(root.right)

应该是单身

rtemp = subtree_min_and_max(root.left)

此时,子树的右孩子为空,程序应在左孩子中搜索 min 和 max。

【讨论】:

以上是关于在递归二叉树函数中返回元组时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

终于搞明白了二叉树的递归函数是否需要返回值

LeetCode 814. 二叉树剪枝

假设二叉树以二叉链表作为存储结构,试设计一个计算二叉树叶子结点树的递归算 法 要求用递归算法啊

二叉树的递归算法

二叉树的函数实现

用于在 JavaScript 中的二叉树中插入节点的递归函数中的错误