[英]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 东西,对算法不是很重要。 看到关键的一点是,它产生了两个新的小树林,他们最终成为了left
和right
返回树的属性。 (这也有效,因为我对__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.