Python 中具有递归函数的决策二叉树实现
Decision Binary Tree implementation in Python with recursive function
我是数据结构的初学者,我正在使用 Python 从列表创建决策二叉树,列表的元素应该在叶子中。列表的长度总是一对数字。
我创建了一个二叉树的数据结构:
class BinaryTree:
def __init__(self, value):
self.value= value
self.left = None
self.right = None
def insert_left(self, value):
if self.left == None:
self.left = BinaryTree(value)
else:
new_node = BinaryTree(value)
new_node.left = self.left
self.left= new_node
def insert_right(self, value):
if self.right== None:
self.right= BinaryTree(value)
else:
new_node = BinaryTree(value)
new_node.right= self.right
self.right= new_node
def get_value(self):
return self.value
def get_left(self):
return self.left
def get_right(self):
return self.right
我创建了一个递归函数来实现树:
def cons_tree(leaflist):
size = len(leaflist)
tag = int(math.log(size)/math.log(2))
return cons_tree_sub(tag, leaflist)
def cons_tree_sub(tag, leaflist):
size = len(leaflist)
abd = BinaryTree(tag)
if size < 3:
abd.insert_left(leaflist[0])
abd.insert_right(leaflist[1])
else :
mid= size//2
subList1= leaflist[:mid]
subList2= leaflist[mid:]
#the code in java is :
#return new Node(tag,cons_tree_sub(tag-1,subList1),cons_tree_sub(tag-1,subList2));
abd.insert_left(cons_tree_sub(tag-1, subList1))
abd.insert_right(cons_tree_sub(tag-1, subList2))
return abd
def display(T):
if T != None:
print (T.get_value(),display(T.get_left()),display(T.get_right()))
abd = cons_tree([False, True, True, False, False, True, False, False])
display(abd)
当我执行程序时,我得到了这个结果:
_________________________3__________________________
/ \
<__main__.BinaryTree object at 0x000002B3F25E8F70> <__main__.BinaryTree object at 0x000002B3F25E87C0>
我明白当我在左边或右边插入时我插入的是一棵树而不是一个值,我如何才能在递归函数中实现所有的树children
我尝试为 return 函数执行 get_value() 因为它 return 是一棵树 :
abd.insert_left(cons_tree_sub(tag-1, subList1).get_value())
abd.insert_right(cons_tree_sub(tag-1, subList2).get_value())
但我的结果是树不完整:
3
/ \
2 2
我想要的结果是:
__________3__________
/ \
____2____ ____2_____
/ \ / \
__1__ _1__ __1__ __1__
/ \ / \ / \ / \
False True True False False True False False
主要问题在这里:
abd.insert_left(cons_tree_sub(tag-1, subList1))
因为abd.insert_left
需要一个值作为参数,但是你传递给它一个节点实例(因为这就是cons_tree_sub
returns) .
也一样:
abd.left = cons_tree_sub(tag-1, subList1)
...或创建一个 setter,或更改 insert_left
以便它也可以处理节点实例。
我会更改节点构造函数,以便它可以选择为左右子节点获取参数:
def __init__(self, value, left=None, right=None):
self.value= value
self.left = left
self.right = right
我也会为递归使用更原子的基本情况,并利用 math.log2
.
那你可以精简代码,写cons_tree
如下:
def cons_tree(lst):
size = len(lst)
if size == 1:
return BinaryTree(lst[0])
mid = size//2
return BinaryTree(int(math.log2(size)), cons_tree(lst[:mid]), cons_tree(lst[mid:]))
您正在使用自上而下的方法,从顶部构建树并在树中插入值。
我建议采用自下而上的方法,从底部构建树并将两棵小树合并成一棵大树。
一种方法是向 class Tree
添加一个新的 .__init__
方法,以允许从两个子树构建树:
class Tree:
def __init__(self, v, l=None, r=None):
self.value = v
self.left = l
self.right = r
def __repr__(self):
if self.left is None and self.right is None:
return repr(self.value)
else:
return 'T({},{},{})'.format(self.value, self.left, self.right)
def build_tree(seq):
if len(seq) == 1:
return Tree(1, seq[0], None)
elif len(seq) == 2:
return Tree(1, seq[0], seq[1])
else:
m = (len(seq) + 1) // 2
l = build_tree(seq[:m])
r = build_tree(seq[m:])
return Tree(max(l.value, r.value) + 1, l, r)
print( build_tree([False, True, True, False, False, True, False, False]) )
# T(3,T(2,T(1,False,True),T(1,True,False)),T(2,T(1,False,True),T(1,False,False)))
我是数据结构的初学者,我正在使用 Python 从列表创建决策二叉树,列表的元素应该在叶子中。列表的长度总是一对数字。
我创建了一个二叉树的数据结构:
class BinaryTree:
def __init__(self, value):
self.value= value
self.left = None
self.right = None
def insert_left(self, value):
if self.left == None:
self.left = BinaryTree(value)
else:
new_node = BinaryTree(value)
new_node.left = self.left
self.left= new_node
def insert_right(self, value):
if self.right== None:
self.right= BinaryTree(value)
else:
new_node = BinaryTree(value)
new_node.right= self.right
self.right= new_node
def get_value(self):
return self.value
def get_left(self):
return self.left
def get_right(self):
return self.right
我创建了一个递归函数来实现树:
def cons_tree(leaflist):
size = len(leaflist)
tag = int(math.log(size)/math.log(2))
return cons_tree_sub(tag, leaflist)
def cons_tree_sub(tag, leaflist):
size = len(leaflist)
abd = BinaryTree(tag)
if size < 3:
abd.insert_left(leaflist[0])
abd.insert_right(leaflist[1])
else :
mid= size//2
subList1= leaflist[:mid]
subList2= leaflist[mid:]
#the code in java is :
#return new Node(tag,cons_tree_sub(tag-1,subList1),cons_tree_sub(tag-1,subList2));
abd.insert_left(cons_tree_sub(tag-1, subList1))
abd.insert_right(cons_tree_sub(tag-1, subList2))
return abd
def display(T):
if T != None:
print (T.get_value(),display(T.get_left()),display(T.get_right()))
abd = cons_tree([False, True, True, False, False, True, False, False])
display(abd)
当我执行程序时,我得到了这个结果:
_________________________3__________________________
/ \
<__main__.BinaryTree object at 0x000002B3F25E8F70> <__main__.BinaryTree object at 0x000002B3F25E87C0>
我明白当我在左边或右边插入时我插入的是一棵树而不是一个值,我如何才能在递归函数中实现所有的树children
我尝试为 return 函数执行 get_value() 因为它 return 是一棵树 :
abd.insert_left(cons_tree_sub(tag-1, subList1).get_value())
abd.insert_right(cons_tree_sub(tag-1, subList2).get_value())
但我的结果是树不完整:
3
/ \
2 2
我想要的结果是:
__________3__________
/ \
____2____ ____2_____
/ \ / \
__1__ _1__ __1__ __1__
/ \ / \ / \ / \
False True True False False True False False
主要问题在这里:
abd.insert_left(cons_tree_sub(tag-1, subList1))
因为abd.insert_left
需要一个值作为参数,但是你传递给它一个节点实例(因为这就是cons_tree_sub
returns) .
也一样:
abd.left = cons_tree_sub(tag-1, subList1)
...或创建一个 setter,或更改 insert_left
以便它也可以处理节点实例。
我会更改节点构造函数,以便它可以选择为左右子节点获取参数:
def __init__(self, value, left=None, right=None):
self.value= value
self.left = left
self.right = right
我也会为递归使用更原子的基本情况,并利用 math.log2
.
那你可以精简代码,写cons_tree
如下:
def cons_tree(lst):
size = len(lst)
if size == 1:
return BinaryTree(lst[0])
mid = size//2
return BinaryTree(int(math.log2(size)), cons_tree(lst[:mid]), cons_tree(lst[mid:]))
您正在使用自上而下的方法,从顶部构建树并在树中插入值。
我建议采用自下而上的方法,从底部构建树并将两棵小树合并成一棵大树。
一种方法是向 class Tree
添加一个新的 .__init__
方法,以允许从两个子树构建树:
class Tree:
def __init__(self, v, l=None, r=None):
self.value = v
self.left = l
self.right = r
def __repr__(self):
if self.left is None and self.right is None:
return repr(self.value)
else:
return 'T({},{},{})'.format(self.value, self.left, self.right)
def build_tree(seq):
if len(seq) == 1:
return Tree(1, seq[0], None)
elif len(seq) == 2:
return Tree(1, seq[0], seq[1])
else:
m = (len(seq) + 1) // 2
l = build_tree(seq[:m])
r = build_tree(seq[m:])
return Tree(max(l.value, r.value) + 1, l, r)
print( build_tree([False, True, True, False, False, True, False, False]) )
# T(3,T(2,T(1,False,True),T(1,True,False)),T(2,T(1,False,True),T(1,False,False)))