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

 

 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小斌哥ge

非常感谢,祝你一切顺利。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值