简体   繁体   English

Python:递归:查找二叉树的叶数

[英]Python: Recursion: Find number of leaves of binary tree

I am trying to write a function that calculates the number of leaves of a binary tree by incorporating my BinaryTree class: 我正在尝试编写一个函数,通过合并我的BinaryTree类来计算二叉树的叶数:

This is my BinaryTree class: 这是我的BinaryTree类:

class BinaryTree:

def __init__(self, data):
    self.data = data
    self.left = None
    self.right = None

def insert_left(self, new_data):
    if self.left == None:
        self.left = BinaryTree(new_data)
    else:
        t = BinaryTree(new_data)
        t.left = self.left
        self.left = t

def insert_right(self, new_data):
    if self.right == None:
        self.right = BinaryTree(new_data)
    else:
        t = BinaryTree(new_data)
        t.right = self.right
        self.right = t

def get_left(self):
    return self.left

def get_right(self):
    return self.right

def set_data(self, data):
    self.data = data

def get_data(self):
    return self.data

And this the function that I wrote: at the moment its not outputting the right values. 这就是我写的功能:目前它没有输出正确的值。 I think there is something wrong with my recursion but I cannot figure it out: 我认为我的递归有问题,但我无法弄清楚:

def num_leaves(my_tree):
    count = 0
    if my_tree.get_left() and my_tree.get_right() is None:
        count += 1
    if my_tree.get_left():
        num_leaves(my_tree.get_left())
    if my_tree.get_right():
        num_leaves(my_tree.get_right())

    return count

an example of an input and output would be: 输入和输出的一个例子是:

a = BinaryTree(1)
a.insert_left(2)
a.insert_right(3)
print(num_leaves(a))

output: 输出:

0 

instead of 2. 而不是2。

The idea behind my function is that it recurs until it finds a node where the left and right subtree are None, then it adds one to count. 我的函数背后的想法是它重复出现,直到它找到左和右子树为None的节点,然后它添加一个来计数。 This way it finds each leaf. 这样它就能找到每片叶子。

What am I doing wrong? 我究竟做错了什么?

You misunderstand the independence of recursive calls. 你误解了递归调用的独立性。 num_leaves cannot return anything except 0 or 1 (as you wrote it). num_leaves不能返回除0或1之外的任何内容(如您所写)。 Every instance of num_leaves has its own local copy of count . num_leaves的每个实例都有自己的count本地副本。 Instead of trying to do this as a running sum, have num_leaves return the number of leaves at or beneath this point. 不要尝试将此作为运行总和, 而是num_leaves返回此点或此点之下的叶数。

Also, you've misused the boolean expression in num_leaves's first if statement. 另外,你在num_leaves的第一个if语句中误用了布尔表达式。 You didn't explicitly check to see if the left tree is None. 您没有明确检查左侧树是否为None。 Although what you wrote happens to work the same way, it looks to me like you didn't realize what you're doing. 虽然你所写的内容恰好以相同的方式工作,但在我看来你并没有意识到你在做什么。

def num_leaves(my_tree):
    if my_tree is None:
        return 0
    else:
        return num_leaves(my_tree.get_left()) +
               num_leaves(my_tree.get_right())

At first glance your code for num_leaves should be like this: 乍一看, num_leaves的代码应如下所示:

def num_leaves(my_tree):
    count = 0
    if my_tree.get_left() is None and my_tree.get_right() is None:
        count += 1
    if my_tree.get_left():
        count += num_leaves(my_tree.get_left()) # added count +=
    if my_tree.get_right():
        count += num_leaves(my_tree.get_right()) # added count +=

    return count

I'll post some more improvements to your Tree code. 我将对您的Tree代码发布一些更多改进。 The way you have implemented it your BinaryTree is simply a binary tree and not a binary search tree. 你实现它的方式你的BinaryTree只是一个二叉树而不是二叉搜索树。 So I guess if you make the simple change I proposed to your code above, it should work fine. 所以我想如果你做了我上面提到的代码的简单改变,它应该可以正常工作。

Testing: 测试:

This gives 3, as expected: 这正如预期的那样给出3:

a = BinaryTree(1)
a.insert_left(2)
a.insert_right(3)
a.insert_right(4)
a.get_right().insert_left(5)
print(num_leaves(a))

This gives 2, as expected: 这给出了2,如预期的那样:

a = BinaryTree(1)
a.insert_left(2)
a.insert_right(3)
print(num_leaves(a))

This gives 2, as expected: 这给出了2,如预期的那样:

a = BinaryTree(1)
a.insert_left(2)
a.insert_right(3)
a.get_right().insert_left(5)
print(num_leaves(a))

I would recommend to keep all btree related functions inside the class. 我建议将所有btree相关的函数保留在类中。 That's OOP. 那是OOP。

class BinaryTree:
    ... your code ...

    def is_leaf(self):
        return self.right is None and self.left is None

    def count_leaves(self):
        if self.is_leaf():
            return 1
        count = 0
        if self.right is not None:
            count += self.right.count_leaves()
        if self.left is not None:
            count += self.left.count_leaves()
        return count

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

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