Python 层次填充二叉树
为了更好地理解递归函数,我尝试为二叉树创建一个Python脚本,该脚本插入值,在进入下一个之前完全填充级别 这是我的树节点实现:Python 层次填充二叉树,python,binary-tree,Python,Binary Tree,为了更好地理解递归函数,我尝试为二叉树创建一个Python脚本,该脚本插入值,在进入下一个之前完全填充级别 这是我的树节点实现: class Node: def __init__(self, value): self.value = value self.right_child = None self.left_child = None self.parent = None class Tree: def __in
class Node:
def __init__(self, value):
self.value = value
self.right_child = None
self.left_child = None
self.parent = None
class Tree:
def __init__(self):
self.root = None
我现在遇到的问题是设置满足该标准的条件
举个例子:这里我按顺序添加以下数字:12、5、18、2、9、15、19、13、17。因此,将内容放入下一级的唯一条件是父级内容已填充
_12_______
/ \
5 __18_
/ \ / \
2 9 15_ 19
/ \
13 17
这就是我到目前为止所做的:
def插入(自身,值):
如果(self.root==无):
self.root=节点(值)
其他:
self.\u插入(值,self.root)
def_插入(自身、值、curNode):
如果(curNode.left_child==无):
curNode.left_child=节点(值)
curNode.left\u child.parent=curNode
elif(curNode.right\u child==None):
curNode.right\u child=节点(值)
curNode.right\u child.parent=curNode
其他:
self.\u插入(值,curNode.left\u子项)
其中:
_12_
/ \
__5 18
/ \
__2_ 9
/ \
15_ 19
/ \
13 17
因此忽略了所有正确的孩子。当然,问题是我的代码的最后一个
else
。我怎样才能让它同时考虑节点的左右两个孩子? 实际上,您不需要一个包含左右指针的节点结构。只需将整个树存储在一个数组中,以便索引N
处节点的子节点位于2*N+1
和2*N+2
:
def print_tree(items, pos, level):
if pos >= len(items):
return
print('.' * level, items[pos])
print_tree(items, pos * 2 + 1, level + 1)
print_tree(items, pos * 2 + 2, level + 1)
print_tree([12, 5, 18, 2, 9 , 15, 19, 13, 17], 0, 0)
印刷品
12
. 5
.. 2
... 13
... 17
.. 9
. 18
.. 15
.. 19
这就是你想要的
这被称为一个
如果您正在寻找一个搜索树(一个维护值顺序的树),并且希望保持它的平衡,那么看看是表示这一点的明智方法。但是,如果您对如何使用树结构来获得相同的结果感兴趣,可以将问题分为两部分:首先查找最浅的未完成节点,然后向其中添加新节点。这是一种方法:
class Node:
def __init__(self, value):
self.value = value
self.right_child = None
self.left_child = None
self.parent = None
class Tree:
def __init__(self):
self.root = None
def insert(self, value):
if self.root is None:
self.root = Node(value)
else:
# Find shallowest incomplete node (ignore returned depth)
node, _ = Tree._next_insertion_node(self.root)
# Add new node to it
if node.left_child is None:
node.left_child = Node(value)
else:
node.right_child = Node(value)
@staticmethod
def _next_insertion_node(node, level=0):
# Returns shallowest incomplete node and its depth
if node.left_child is None or node.right_child is None:
return node, level
node_left, level_left = Tree._next_insertion_node(node.left_child, level + 1)
node_right, level_right = Tree._next_insertion_node(node.right_child, level + 1)
if level_left <= level_right:
return node_left, level_left
else:
return node_right, level_right
def print(self):
Tree._print_node(self.root)
@staticmethod
def _print_node(node, level=0):
if node is None: return
print(' ' * (level * 2), '*', node.value)
Tree._print_node(node.left_child, level + 1)
Tree._print_node(node.right_child, level + 1)
numbers = [12, 5, 18, 2, 9 , 15, 19, 13, 17]
tree = Tree()
for number in numbers:
tree.insert(number)
tree.print()
# * 12
# * 5
# * 2
# * 13
# * 17
# * 9
# * 18
# * 15
# * 19
类节点:
定义初始值(自身,值):
自我价值=价值
self.right\u child=无
self.left\u child=无
self.parent=None
类树:
定义初始化(自):
self.root=None
def插入(自身,值):
如果self.root为无:
self.root=节点(值)
其他:
#查找最浅的不完整节点(忽略返回的深度)
节点,\=树。\\下一个\插入\节点(self.root)
#向其中添加新节点
如果node.left_子项为无:
node.left_child=节点(值)
其他:
node.right\u child=节点(值)
@静力学方法
定义下一个插入节点(节点,级别=0):
#返回最浅的未完成节点及其深度
如果node.left\u child为None或node.right\u child为None:
返回节点,级别
node_left,level_left=树。_next_insertion_节点(node.left_子节点,level+1)
node_right,level_right=树。_next_insertion_节点(node.right_子节点,level+1)
如果level_left不确定这是最好的方法,但我尝试写一些类似于您尝试的方法。我们没有立即转到左侧节点,而是记录这两个节点,然后迭代以查看它们。首先是根,然后是根。左,根。右,根。左。左,根。左。右,根。右。左。。。等
类节点:
定义初始值(自身,值):
自我价值=价值
self.right\u child=无
self.left\u child=无
self.parent=None
类树:
定义初始化(自):
self.root=None
#记录需要处理的节点。
节点到进程=[]
def插入(自身,值):
如果(self.root==无):
self.root=节点(值)
其他:
#添加要处理的节点
self.nodes\u to\u process.append(self.root)
自插入(值)
def_插入(自身,值):
#当前节点是列表中的下一个节点。
curNode=self.nodes\u到\u进程[0]
如果(curNode.left_child==无):
curNode.left_child=节点(值)
curNode.left\u child.parent=curNode
#重置列表,因为我们已插入。
self.nodes_to_进程=[]
elif(curNode.right\u child==None):
curNode.right\u child=节点(值)
curNode.right\u child.parent=curNode
#重置列表,因为我们已插入。
self.nodes_to_进程=[]
其他:
#插入两个子节点。
self.nodes\u to\u process.append(curNode.left\u子级)
self.nodes\u to\u process.append(curNode.right\u子节点)
#删除我们刚刚检查的节点。
self.nodes\u to\u process.pop(0)
自插入(值)
这里有一个快速测试
tree=tree()
对于[12,5,18,2,9,15,19,13,17]中的数字:
树。插入(编号)
打印(tree.root.value)#12
打印(tree.root.left_child.value)#5
打印(tree.root.left_child.left_child.value)#2
打印(tree.root.left_child.left_child.left_child.value)#13
打印(tree.root.left_child.left_child.right_child.value)#17
您可能应该提供更多的代码来帮助那些希望帮助您的人,这样他们就可以获得最少的代码示例。您的树类对初学者很有帮助。当然,它是基本树类节点类实现。我现在就在邮报上写。谢谢你说的是一棵二叉树,而不是一棵二叉搜索树,看起来你实际上要做的是以树的形式创建一个类似数据结构。与您当前的方法(在正确的位置插入)不同,更有用的方法可能是“在某个位置插入一片叶子,然后围绕树旋转,直到它平衡”。也调查一下。