python tree 库_Python binarytree库的用法介绍

Python binarytree库的用法介绍

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

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

一、安装binarytree

pip install binarytree

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类中,代码多是因为实现了很多常用的方法,单独看其中一个方法时,代码并不多。

原文链接:https://blog.csdn.net/weixin_43790276/article/details/107993526

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值