为了更好地理解递归函数,我试图为插入值的二叉树创建一个Python脚本,完全填充级别,然后再转到下一个树。
这是我的树节点实现:
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 insert(self,value):
if(self.root==None):
self.root=Node(value)
else:
self._insert(value,self.root)
def _insert(self, value, curNode):
if(curNode.left_child==None):
curNode.left_child=Node(value)
curNode.left_child.parent = curNode
elif(curNode.right_child==None):
curNode.right_child=Node(value)
curNode.right_child.parent = curNode
else:
self._insert(value,curNode.left_child)
给出:
_12_
/ \
__5 18
/ \
__2_ 9
/ \
15_ 19
/ \
13 17
因此忽略了所有正确的孩子。当然,问题是我的代码的最后else
。如何使它同时考虑节点的左子节点和右子节点?
答案 0 :(得分:2)
您实际上不需要为此使用左右指针的节点结构。只需将整个树存储在一个数组中,以使索引为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
这就是你想要的。
这称为binary heap。
如果您要寻找一棵搜索树(一种保持值顺序的树),并且希望保持平衡,请查看https://en.wikipedia.org/wiki/Self-balancing_binary_search_tree
答案 1 :(得分:0)
georg's answer是代表这一点的聪明方法。但是,如果您对如何使用树结构来获得相同的结果感兴趣,则可以将问题分为两部分:首先找到未完成的最浅节点,然后向其添加新节点。这是一种方法:
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
答案 2 :(得分:0)
不确定这是最好的方法,但是我尝试编写与您尝试的方法类似的方法。我们记录两个节点,然后依次遍历,以便我们看到它们,而不是立即转到左边的节点。所以首先是root,然后是root.left,root.right,root.left.left,root.left.right,root.right.left ...等
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
# record nodes that need processing.
nodes_to_process = []
def insert(self,value):
if(self.root==None):
self.root=Node(value)
else:
# add the node to be processed
self.nodes_to_process.append(self.root)
self._insert(value)
def _insert(self,value):
# the current node is the next node in the list.
curNode = self.nodes_to_process[0]
if(curNode.left_child==None):
curNode.left_child=Node(value)
curNode.left_child.parent = curNode
# reset the list, since we've inserted.
self.nodes_to_process = []
elif(curNode.right_child==None):
curNode.right_child=Node(value)
curNode.right_child.parent = curNode
# reset the list, since we've inserted.
self.nodes_to_process = []
else:
# insert the two child nodes.
self.nodes_to_process.append(curNode.left_child)
self.nodes_to_process.append(curNode.right_child)
# Remove the node we've just examined.
self.nodes_to_process.pop(0)
self._insert(value)
这是一个快速测试。
tree = Tree()
for number in [12, 5, 18, 2, 9 , 15, 19, 13, 17]:
tree.insert(number)
print(tree.root.value) # 12
print(tree.root.left_child.value) #5
print(tree.root.left_child.left_child.value) # 2
print(tree.root.left_child.left_child.left_child.value) # 13
print(tree.root.left_child.left_child.right_child.value) # 17