Introduction to the usage of Python binarytree library

Introduction to the usage of Python binarytree library

The binarytree library is a third-party library for Python. This library implements some commonly used methods related to binary trees. When using binary trees, you can call them directly without having to implement them yourself.

At the same time, binary search tree and heap are also implemented in binarytree, which can be called directly.

One, install binarytree

pip install binarytree

In the binarytree library, there are 1 class and 5 functions that can be imported and used by us. The following will introduce the usage of each class or function in turn.

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

Two, tree generates an ordinary binary 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)

operation result:

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): Used to generate a random binary tree, the return value is the root node. There are two parameters, height represents the height of the tree, the default is 3, supports an integer ranging from 0 to 9, an error will be reported if the range is exceeded, is_perfect represents whether the binary tree is full binary tree, the default is False, if it is True, it must be a full binary tree. If it is False, it is not necessarily a full binary tree. The generated tree is random, so the result of each run is different.

Full binary tree: A complete binary tree with all leaf nodes at the bottom is called a full binary tree. A full binary tree is a special case of a complete binary tree. In addition to satisfying the characteristics of a complete binary tree, it also satisfies that all leaf nodes are at the bottom.

Three, bst generates a binary search tree

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)

operation result:

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): Used to generate a random binary search tree, the return value is the root node. There are two parameters, height represents the height of the tree, the default is 3, supports an integer ranging from 0 to 9, and an error will be reported if the range is exceeded. is_perfect indicates whether the binary search tree is a full binary tree. The default is False. If it is True, it must be a full binary tree. If it is False, it is not necessarily a full binary tree. If is_perfect is False, the generated tree is random, so the result of each run is different. If is_perfect is True, the binary search tree generated each time is the same.

Binary search tree has the following characteristics:

1. If the left subtree of the binary tree is not empty, the values ​​of all nodes on the left subtree are less than the value of its root node.

2. If the right subtree of the binary tree is not empty, the values ​​of all nodes on the right subtree are greater than the value of its root node.

3. If you look at it independently, the left subtree and the right subtree are also binary search trees, using recursive thinking until the leaf nodes of the tree.

Four, heap generates a 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)

operation result:

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): Used to generate a random heap, the return value is the root node. There are three parameters, height represents the height of the heap, the default is 3, supports integers ranging from 0 to 9, and an error will be reported if the range is exceeded. is_max indicates whether it is a large top pile, the default is True, if it is True, it is a large top pile, and if it is False, it is a small top pile. is_perfect indicates whether the heap is a full binary tree, the default is False, if it is True, it must be a full binary tree, if it is False, it is not necessarily a full binary tree. The generated tree is random, so the result of each run is different.

The pile structure is divided into large top pile and small top pile:

Big top pile: The value of each node (except leaf nodes) is greater than or equal to the value of its child nodes, and the value of the root node is the largest among all nodes.

Small top heap: The value of each node (except leaf nodes) is less than or equal to the value of its child nodes, and the value of the root node is the smallest among all nodes.

Five, build generates a binary tree based on breadth first

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

operation result:

          _________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): Generate a binary tree based on the provided data list, and the return value is the root node. Add the data in the data list to the binary tree in a breadth-first manner (layer order traversal, that is, from top to bottom, from left to right).

Six, get the parent node of the node

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)

operation result:

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

child_node:  30
parent_node:  17

get_parent(root, child): Find its parent node according to the node in the binary tree, and the return value is the parent node. There are two parameters, root represents the root node of the binary tree, and child represents the child node. If the value passed by child is the root node, the returned parent node result is None.

Seven, construct a binary tree by creating nodes

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

operation result:

  10
 /  \
5    15

Node (object) class: Node is a class used to create a node. There are three parameters during initialization, value represents the value of the node, there is no default value, it is a mandatory parameter, and the parameter passed in must be a number, not a string, etc., otherwise an exception of the wrong type will be thrown. left and right represent the left child node and right child node of the node respectively, which are empty by default. The values ​​of left and right must be instances of the Node class, otherwise an exception of the wrong type will be thrown.

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)

operation result:

    ____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)]

The Node class is used to create nodes, and then associate the nodes to a tree through the left and right attributes. This is a bit cumbersome compared to batch adding.

There are many methods implemented in the Node class, and many methods are decorated with @property as attributes, which can be called directly with the root node. Such as the four traversal methods in the above code.

If you want to know all the methods in the Node class, you can use the built-in method dir() to print all the methods. Such as the properties property, you can return each property value of the current binary tree, and return a dictionary.

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

operation result:

['__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}

The usage of other attributes in the Node class will not be introduced one by one. These attributes are generally well-known.

The source code of the binarytree library is not complicated. The five function codes that can be called are very few. Most of the code implements the Node class. In the Node class, the code is mostly because it implements many commonly used methods. When you look at one of the methods separately , The code is not much.

 

 

Guess you like

Origin blog.csdn.net/weixin_43790276/article/details/107993526