繁体   English   中英

在python中打印二叉树

[英]Printing binary tree in python

我想垂直打印我的二叉树,节点应该是随机数,但我得到的输出不是我想要的。 例如我收到这样的东西:

497985
406204
477464

但是程序应该打印这个:

.....497985
406204
.....477464

我不知道问题出在哪里。 我是编程初学者,所以如果有人可以帮助我,那就太好了。

from numpy.random import randint
import random
from timeit import default_timer as timer


class binarytree:
    def __init__(self):
        self.elem = 0
        self.left = None
        self.right = None


def printtree(tree, h):
    if tree is not None:
        printtree(tree.right, h+1)
        for i in range(1, h):
            print(end = ".....")
        print(tree.elem)
        printtree(tree.left, h+1)


def generate(tree, N, h):
    if N == 0:
        tree = None
    else:
        tree = binarytree()
        x = randint(0, 1000000)
        tree.elem = int(x)
        generate(tree.left, N // 2, h)
        generate(tree.right, N - N // 2 - 1, h)
    printtree(tree, h)

tree = binarytree()
generate(tree, 3, 0)

我重新编写了您的代码,使其更加 Pythonic,并修复了一些错误:

from  random import randrange

class BinaryTree:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

    @classmethod
    def generate_random_tree(cls, depth):
        if depth > 0:
            return cls(randrange(1000000),
                       cls.generate_random_tree(depth - 1),
                       cls.generate_random_tree(depth - 1))
        return None

    def __str__(self):
        """
        Overloaded method to format tree as string
        """
        return "\n".join(self._format())

    def _format(self, cur_depth=0):
        """
        Format tree as string given current depth. This is a generator of
        strings which represent lines of the representation.
        """
        if self.right is not None:
            yield from self.right._format(cur_depth + 1)
        yield "{}{}".format("." * cur_depth, self.val)
        if self.left is not None:
            yield from self.left._format(cur_depth + 1)

print(BinaryTree.generate_random_tree(4))
print()
print(BinaryTree(1,
                 BinaryTree(2),
                 BinaryTree(3,
                            BinaryTree(4),
                            BinaryTree(5))))

这将输出一棵树,它从中间左侧的根生长到右侧的叶子:

...829201
..620327
...479879
.746527
...226199
..463199
...498695
987559
...280755
..168727
...603817
.233132
...294525
..927571
...263402

..5
.3
..4
1
.2

这里打印了一棵随机树和一棵我手动构建的树。 我写它是为了将“正确”的子树打印在顶部 - 如果需要,您可以切换它。

您可以通过一次创建更多点(我认为这是您的h参数?)或将位调整为您想要的任何程序结构来对此进行进一步调整。

这段代码之所以有效,是因为它确保先构建一整棵树,然后再打印它。 这种明显的区别可以更轻松地确保您做对了所有事情。 您的代码在这方面有点混乱 - 您的generate函数确实在每次调用时实例化了一个新的BinaryTree ,但您从未将它们中的任何一个相互关联! 这是因为当您在函数中执行tree = ... ,您所做的只是更改本地名称tree指向的内容 - 它不会更改您传递给它的更高层树的属性!

您的 generate 每次也调用printtree ,但printtree也调用自己......这似乎并不完全正确。

在我的程序中,这个位生成随机树:

    def generate_random_tree(cls, depth):
        if depth > 0:
            return cls(randrange(1000000),
                       cls.generate_random_tree(depth - 1),
                       cls.generate_random_tree(depth - 1))
        return None

classmethod 位只是一些面向对象的 Python 东西,对算法不是很重要。 看到关键的一点是,它产生了两个新的小树林,他们最终成为了leftright返回树的属性。 (这也有效,因为我对__init__做了一些重写)。

这一点基本上打印了树:

    def _format(self, cur_depth=0):
        """
        Format tree as string given current depth. This is a generator of
        strings which represent lines of the representation.
        """
        if self.right is not None:
            yield from self.right._format(cur_depth + 1)
        yield "{}{}".format("." * cur_depth, self.val)
        if self.left is not None:
            yield from self.left._format(cur_depth + 1)

它是一个行的生成器 - 但你可以通过将每个yield ...更改为print(...)yield from s 中删除yield from使其直接打印树。 这里的关键是cur_depth ,它让函数知道它当前在树中的深度,所以它知道要打印多少点,以及它在左右子树上递归调用自己的事实(和你当然,必须检查它们是否为None )。

(这部分是您可以修改以重新引入h )。

暂无
暂无

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

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