Introdução ao uso da biblioteca binarytree Python

Introdução ao uso da biblioteca binarytree Python

A biblioteca binarytree é uma biblioteca de terceiros para Python. Esta biblioteca implementa alguns métodos comumente usados ​​relacionados a árvores binárias. Ao usar árvores binárias, você pode chamá-los diretamente sem ter que implementá-los você mesmo.

Ao mesmo tempo, a árvore de pesquisa binária e o heap também são implementados em binarytree, que pode ser chamada diretamente.

Um, instale binarytree

pip install binarytree

Na biblioteca binarytree, há 1 classe e 5 funções que podem ser importadas e usadas por nós. A seguir, apresentará o uso de cada classe ou função por vez.

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

Dois, a árvore gera uma árvore binária comum

# 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)

resultado da operação:

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): Usado para gerar uma árvore binária aleatória, o valor de retorno é o nó raiz. Existem dois parâmetros, a altura representa a altura da árvore, o padrão é 3, suporta um número inteiro de 0 a 9, um erro será relatado se a faixa for excedida, is_perfect representa se a árvore binária é uma árvore binária completa, o o padrão é False, se for True, deve ser uma árvore binária completa.Se for False, não é necessariamente uma árvore binária completa. A árvore gerada é aleatória, então o resultado de cada execução é diferente.

Árvore binária completa: uma árvore binária completa com todos os nós de folha na parte inferior é chamada de árvore binária completa. Uma árvore binária completa é um caso especial de árvore binária completa. Além de satisfazer as características de uma árvore binária completa, ela também satisfaz que todos os nós folha estejam na parte inferior.

Três, bst gera uma árvore de pesquisa binária

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)

resultado da operação:

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): Usado para gerar uma árvore de pesquisa binária aleatória, o valor de retorno é o nó raiz. Existem dois parâmetros, altura representa a altura da árvore, o padrão é 3, suporta um número inteiro de 0 a 9 e um erro será relatado se o intervalo for excedido. is_perfect indica se a árvore de pesquisa binária é uma árvore binária completa. O padrão é False. Se for True, deve ser uma árvore binária completa. Se for False, não é necessariamente uma árvore binária completa. Se is_perfect for False, a árvore gerada é aleatória, então o resultado de cada execução é diferente.Se is_perfect for True, a árvore de busca binária gerada a cada vez é a mesma.

A árvore de pesquisa binária tem as seguintes características:

1. Se a subárvore esquerda da árvore binária não estiver vazia, os valores de todos os nós na subárvore esquerda são menores que o valor de seu nó raiz.

2. Se a subárvore direita da árvore binária não estiver vazia, os valores de todos os nós na subárvore direita são maiores que o valor de seu nó raiz.

3. Se você olhar para ele de forma independente, a subárvore esquerda e a subárvore direita também são árvores de pesquisa binárias, usando pensamento recursivo até os nós folha da árvore.

Quatro, heap gera um 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)

resultado da operação:

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 (altura = 3, is_max = True, is_perfect = False): Usado para gerar um heap aleatório, o valor de retorno é o nó raiz. Existem três parâmetros, a altura representa a altura do heap, o padrão é 3, suporta números inteiros de 0 a 9 e um erro será relatado se o intervalo for excedido. is_max indica se é uma pilha superior grande, o padrão é True, se for True, é uma pilha superior grande e, se for False, é uma pilha superior pequena. is_perfect indica se o heap é uma árvore binária completa, o padrão é False, se for True, deve ser uma árvore binária completa; se for False, não é necessariamente uma árvore binária completa. A árvore gerada é aleatória, então o resultado de cada execução é diferente.

A estrutura da pilha é dividida em pilha superior grande e pilha superior pequena:

Pilha superior grande: O valor de cada nó (exceto nós folha) é maior ou igual ao valor de seus nós filhos, e o valor do nó raiz é o maior entre todos os nós.

Pilha superior pequena: o valor de cada nó (exceto nós folha) é menor ou igual ao valor de seus nós filhos, e o valor do nó raiz é o menor entre todos os nós.

Quinto, o build gera uma árvore binária com base na largura primeiro

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

resultado da operação:

          _________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 (valores): Gere uma árvore binária com base na lista de dados fornecida e o valor de retorno é o nó raiz. Adicione os dados da lista de dados à árvore binária de maneira ampla (passagem da ordem das camadas, ou seja, de cima para baixo, da esquerda para a direita).

Seis, obtenha o nó pai do nó

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)

resultado da operação:

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

child_node:  30
parent_node:  17

get_parent (root, child): Encontre seu nó pai de acordo com o nó na árvore binária, e o valor de retorno é o nó pai. Existem dois parâmetros, root representa o nó raiz da árvore binária e filho representa o nó filho. Se o valor passado pelo filho for o nó raiz, o resultado do nó pai retornado será Nenhum.

Sete, construa uma árvore binária criando nós

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

resultado da operação:

  10
 /  \
5    15

Classe do nó (objeto): o nó é uma classe usada para criar um nó. Existem três parâmetros durante a inicialização, o valor representa o valor do nó, não há valor padrão, é um parâmetro obrigatório e o parâmetro passado deve ser um número, não uma string, etc., caso contrário, uma exceção do errado tipo será lançado. esquerda e direita representam o nó filho esquerdo e o nó filho direito do nó, respectivamente, que estão vazios por padrão. Os valores de esquerda e direita devem ser instâncias da classe Node, caso contrário, uma exceção do tipo errado será lançada.

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)

resultado da operação:

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

A classe Node é usada para criar nós e, em seguida, associá-los a uma árvore por meio dos atributos esquerdo e direito. Isso é um pouco complicado em comparação com a adição em lote.

Existem muitos métodos implementados na classe Node, e muitos métodos são decorados com @property como atributos, que podem ser chamados diretamente com o nó raiz. Como os quatro métodos de passagem no código acima.

Se quiser saber todos os métodos da classe Node, você pode usar o método interno dir () para imprimir todos os métodos. Como a propriedade properties, você pode retornar cada valor de propriedade da árvore binária atual e retornar um dicionário.

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

resultado da operação:

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

O uso de outros atributos na classe Node não será introduzido um por um. Esses atributos são geralmente bem conhecidos.

O código-fonte da biblioteca binarytree não é complicado. Os cinco códigos de função que podem ser chamados são muito poucos. A maior parte do código é para implementar a classe Node. Na classe Node, o código é principalmente porque implementa muitos métodos comumente usados Quando você examina um dos métodos separadamente, o código não é muito.

 

 

Acho que você gosta

Origin blog.csdn.net/weixin_43790276/article/details/107993526
Recomendado
Clasificación