0
点赞
收藏
分享

微信扫一扫

Python binarytree库的用法介绍


Python binarytree库的用法介绍

binarytree 库是一个 Python 的第三方库。这个库实现了一些二叉树相关的常用方法,使用二叉树时,可以直接调用,不需要再自己实现。

同时,binarytree 里还实现了二叉搜索树和堆,可以直接调用。

一、安装binarytree

pip install binarytree

在binarytree库中,可以供我们导入使用的有1个类和5个函数。下面会依次介绍每一个类或函数的用法。

__all__ = ['Node', 'tree', 'bst', 'heap', 'build', 'get_parent']

二、tree生成一棵普通二叉树

# coding=utf-8
from binarytree import *


tree0 = tree()
print('tree0:', tree0)
tree1 = tree(height=2, is_perfect=True)
print('tree1:', tree1)
tree2 = tree(height=2, is_perfect=False)
print('tree2:', tree2)

运行结果:

tree0: 
_______13_____
/ \
___11__ _0__
/ \ / \
1 6 10 8
\ / \ / / \
14 2 3 5 9 4

tree1:
__2__
/ \
3 4
/ \ / \
1 5 6 0

tree2:
2__
/ \
0 6
/ /
3 1

tree(height=3, is_perfect=False): 用于生成一棵随机的二叉树,返回值是根节点。有两个参数,height 表示树的高度,默认为3,支持范围为0~9的整数,超出范围会报错,is_perfect 表示二叉树是否为满二叉树,默认为False,如果为True则一定是满二叉树,如果为False则不一定为满二叉树。生成的树是随机的,所以每次运行结果不一样。

满二叉树:所有叶节点都在最底层的完全二叉树称为满二叉树。满二叉树是完全二叉树中的特殊情况,除了满足完全二叉树的特征,还满足所有叶节点都在最底层。

三、bst生成一棵二叉搜索树

bst0 = bst()
print('bst0:', bst0)
bst1 = bst(height=2, is_perfect=True)
print('bst1:', bst1)
bst2 = bst(height=2, is_perfect=False)
print('bst2:', bst2)

运行结果:

bst0: 
____4______
/ \
0__ __11___
\ / \
3 8 _13
/ / \ / \
1 7 9 12 14

bst1:
__3__
/ \
1 5
/ \ / \
0 2 4 6

bst2:
__3
/ \
1 4
/ \
0 2

bst(height=3, is_perfect=False): 用于生成一棵随机的二叉搜索树,返回值是根节点。有两个参数,height 表示树的高度,默认为3,支持范围为0~9的整数,超出范围会报错。is_perfect 表示二叉搜索树是否为满二叉树,默认为False,如果为True则一定是满二叉树,如果为False则不一定为满二叉树。如果 is_perfect 为False生成的树是随机的,所以每次运行结果不一样,如果 is_perfect 为True,则每次生成的二叉搜索树都一样。

二叉搜索树具有如下特性:

1. 如果二叉树的左子树不为空,则左子树上所有节点的值均小于它的根节点的值。

2. 如果二叉树的右子树不为空,则右子树上所有节点的值均大于它的根节点的值。

3. 如果独立地看,左子树、右子树也分别为二叉搜索树,用递归的思想,直到树的叶节点。

四、heap生成一个堆

heap0 = heap()
print('heap0:', heap0)
heap1 = heap(height=2, is_max=True, is_perfect=True)
print('heap1:', heap1)
heap2 = heap(height=2, is_max=False, is_perfect=True)
print('heap2:', heap2)
heap3 = heap(height=2, is_max=False, is_perfect=False)
print('heap3:', heap3)

运行结果:

heap0: 
_______14________
/ \
__10__ ____13__
/ \ / \
8 9 12 5
/ \ / \ / \ / \
7 2 6 3 1 11 4 0

heap1:
__6__
/ \
5 4
/ \ / \
1 2 3 0

heap2:
__0__
/ \
4 1
/ \ / \
6 5 2 3

heap3:
__1
/ \
4 3
/ \
6 5

heap(height=3, is_max=True, is_perfect=False): 用于生成一个随机的堆,返回值是根节点。有三个参数,height 表示堆的高度,默认为3,支持范围为0~9的整数,超出范围会报错。is_max 表示是否为大顶堆,默认为True,如果为True则是大顶堆,如果为False则是小顶堆。is_perfect 表示堆是否为满二叉树,默认为False,如果为True则一定是满二叉树,如果为False则不一定为满二叉树。生成的树是随机的,所以每次运行结果不一样。

堆结构分为大顶堆和小顶堆:

大顶堆:每个节点(叶节点除外)的值都大于等于其子节点的值,根节点的值是所有节点中最大的。

小顶堆:每个节点(叶节点除外)的值都小于等于其子节点的值,根节点的值是所有节点中最小的。

五、build按广度优先生成一棵二叉树

values = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
build_tree = build(values)
print(build_tree)
print(build_tree.values)

运行结果:

          _________10______
/ \
___17__ _50
/ \ / \
_7 30 _24 27
/ \ / \ /
45 15 5 36 21

[10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]

build(values): 根据提供的数据列表生成一棵二叉树,返回值是根节点。将数据列表中的数据按广度优先的方式添加到二叉树中(层序遍历,即从上到下、从左到右)。

六、获取节点的父节点

values = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
build_tree = build(values)
print(build_tree)
child_node = build_tree.left.right
print('child_node: ', child_node.value)
parent = get_parent(build_tree, child_node)
print('parent_node: ', parent.value)

运行结果:

          _________10______
/ \
___17__ _50
/ \ / \
_7 30 _24 27
/ \ / \ /
45 15 5 36 21

child_node: 30
parent_node: 17

get_parent(root, child): 根据二叉树中的节点找到它的父节点,返回值是父节点。有两个参数,root 表示二叉树的根节点,child 表示子节点。如果 child 传入的值是根节点,则返回的父节点结果为 None 。

七、通过创建节点来构造二叉树

root = Node(10)
root.left = Node(5)
root.right = Node(15)
print(root)

运行结果:

  10
/ \
5 15

Node(object)类: Node是一个类,用于创建一个节点。初始化时有三个参数,value 表示节点的值,没有默认值,是必传参数,且传入的参数必须是数字,不能是字符串等,否则抛出类型错误的异常。left 和 right 分别表示节点的左子节点和右子节点,默认为空,left 和 right 的值必须是 Node 类的实例,否则抛出类型错误的异常。

data = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
nodes = [None if i is None else Node(i) for i in data]
root = nodes[0]
root.left = nodes[1]
root.right = nodes[2]
root.left.left = nodes[3]
root.left.right = nodes[4]
root.right.left = nodes[5]
root.right.right = nodes[6]
root.pprint()
print('层序遍历: ', root.levelorder)
print('先序遍历: ', root.preorder)
print('中序遍历: ', root.inorder)
print('后序遍历: ', root.postorder)

运行结果:

    ____10___
/ \
17 _50
/ \ / \
7 30 24 27

层序遍历: [Node(10), Node(17), Node(50), Node(7), Node(30), Node(24), Node(27)]
先序遍历: [Node(10), Node(17), Node(7), Node(30), Node(50), Node(24), Node(27)]
中序遍历: [Node(7), Node(17), Node(30), Node(10), Node(24), Node(50), Node(27)]
后序遍历: [Node(7), Node(30), Node(17), Node(24), Node(27), Node(50), Node(10)]

Node类用于创建节点,然后通过left和right两个属性来将节点关联到一棵树中,这相对于批量添加来说,操作有点繁琐。

Node类中实现了很多的方法,并且很多方法都使用 @property 装饰成了属性,可以直接用根节点来调用这些属性。如上面代码中的四种遍历方法。

想知道 Node 类中的所有方法,可以使用内置方法 dir() 将所有方法打印出来。如 properties 属性,可以返回当前二叉树的每一个属性值,返回一个字典。

print(dir(root))
print(root.properties)

运行结果:

['__class__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'height', 'inorder', 'is_balanced', 'is_bst', 'is_complete', 'is_max_heap', 'is_min_heap', 'is_perfect', 'is_strict', 'is_symmetric', 'leaf_count', 'leaves', 'left', 'levelorder', 'levels', 'max_leaf_depth', 'max_node_value', 'min_leaf_depth', 'min_node_value', 'postorder', 'pprint', 'preorder', 'properties', 'right', 'size', 'val', 'validate', 'value', 'values']
{'height': 2, 'size': 7, 'is_max_heap': False, 'is_min_heap': False, 'is_perfect': True, 'is_strict': True, 'is_complete': True, 'leaf_count': 4, 'min_node_value': 7, 'max_node_value': 50, 'min_leaf_depth': 2, 'max_leaf_depth': 2, 'is_bst': False, 'is_balanced': True, 'is_symmetric': False}

关于Node类中其他属性的用法就不一一介绍了,这些属性一般都是能见名知义的。

binarytree 库的源码并不复杂,可供调用的5个函数代码都很少,大部分代码是实现Node类,在Node类中,代码多是因为实现了很多常用的方法,单独看其中一个方法时,代码并不多。

 

Python binarytree库的用法介绍_binarytree模块

 

举报

相关推荐

0 条评论