Implementação ES6 da estrutura de dados da árvore de pesquisa binária com suporte TypeScript.
Visite as diretrizes de contribuição para saber mais sobre como traduzir este documento para mais idiomas.
yarn add binstree
npm install binstree
Uma árvore de pesquisa binária é uma estrutura de dados de árvore binária enraizada, cujos nós contêm uma key
exclusiva e um value
associado e apontam para duas subárvores distintas left
e right
. A árvore satisfaz a propriedade de pesquisa binária, portanto a chave em cada nó é maior que qualquer chave armazenada na subárvore esquerda e menor que qualquer chave armazenada na subárvore direita. Como resultado iminente deste princípio, as operações em árvore são muito beneficiadas, pois em média cada comparação de chaves permite que as operações pulem cerca de metade da árvore, de modo que cada inserção, exclusão ou consulta leva um tempo proporcional ao logaritmo do número de nós armazenado na árvore.
Binstree expõe uma API encadeada, que pode ser utilizada através de uma sintaxe simples e mínima, permitindo combinar métodos de forma eficaz.
Exemplos de uso também podem ser encontrados no diretório test
.
'use strict' ;
const { Tree , Node } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
//=> Tree { root: null }
tree . insert ( 10 , 'A' ) ;
// => Tree { root: Node { left: null, right: null, key: 10, value: 'A' } }
tree . root ;
//=> Node { left: null, right: null, key: 10, value: 'A' }
const node = new Node ( 10 , 'A' ) ;
tree . root . key === node . key ;
//=> true
tree . root . value === node . value ;
//=> true
tree . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) . root ;
//=> Node { left: [Node], right: [Node], key: 10, value: 'A' }
tree . root . left ;
//=> Node { left: null, right: null, key: 5, value: 'B' }
tree . root . right ;
//=> Node { left: null, right: null, key: 15, value: 'C' }
tree . insert ( 2 , 'D' ) . insert ( 7 , 'E' ) . insert ( 12 , 'F' ) . insert ( 20 , 'G' ) ;
tree . search ( 5 ) ;
//=> Node { key: 5, value: 'B',
// left: Node { left: null, right: null, key: 2, value: 'D' },
// right: Node { left: null, right: null, key: 7, value: 'E' } }
tree . search ( 15 ) ;
//=> Node { key: 15, value: 'C',
// left: Node { left: null, right: null, key: 12, value: 'F' },
// right: Node { left: null, right: null, key: 20, value: 'G' } }
tree . includes ( 12 ) ;
//=> true
tree . includes ( 100 ) ;
//=> false
tree . height ( ) ;
//=> 2
tree . isBalanced ( ) ;
//=> true
tree . remove ( 10 ) . root ;
//=> Node { key: 12, value: 'F',
// left: Node { left: [Node], right: [Node], key: 5, value: 'B' },
// right: Node { left: null, right: [Node], key: 15, value: 'C' } }
tree . isBalanced ( ) ;
//=> false
insert(key, value)
Tree
Muda a árvore inserindo um novo nó no local apropriado.
key
Number
Pode ser qualquer número que corresponda à key
do nó criado. Cada nó possui sua própria key
exclusiva.
value
Any
Pode ser qualquer valor que será armazenado no nó criado.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) ;
// => Tree { root: Node { key: 10, value: 'A', left: null, right: null } }
root
Node | null
Retorna o nó raiz da árvore. Se a árvore estiver vazia, será retornado null
.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) ;
// => Tree { root: Node { key: 10, value: 'A', left: null, right: null } }
tree . root ;
// => Node { key: 10, value: 'A', left: null, right: null }
isEmpty()
Boolean
Determina se a árvore está vazia, retornando true
ou false
conforme apropriado.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) ;
tree . isEmpty ( ) ;
// => false
remove(key)
Tree
Muda a árvore removendo o nó correspondente ao argumento key
.
key
Number
Pode ser qualquer número que corresponda à key
de um nó existente.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) ;
tree . remove ( 10 ) ;
//=> Tree { root: null }
includes(key)
Boolean
Determina se a árvore inclui um nó com uma determinada key
, retornando true
ou false
conforme apropriado.
key
Number
key
do nó a ser pesquisada.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) ;
tree . includes ( 10 ) ;
// => true
tree . includes ( 25 ) ;
// => false
tree . includes ( 5 ) ;
// => true
search(key)
Node | null
Determina se a árvore inclui um nó com uma determinada key
, retornando o nó de destino ou null
conforme apropriado.
key
Number
key
do nó a ser pesquisada.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) ;
tree . search ( 10 ) ;
// => Node { key: 10, value: 'A', left: [Node], right: null }
tree . search ( 25 ) ;
// => null
tree . search ( 5 ) ;
// => Node { key: 5, value: 'B', left: null, right: null }
min()
Node | null
Retorna o nó mais à esquerda da árvore, portanto, o nó correspondente à key
mínima.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 0 , 'C' ) ;
tree . min ( ) ;
// => Node { key: 0, value: 'C', left: null, right: null }
max()
Node | null
Retorna o nó mais à direita da árvore, portanto, o nó correspondente à key
máxima.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 15 , 'B' ) . insert ( 25 , 'C' ) ;
tree . max ( ) ;
// => Node { key: 25, value: 'C', left: null, right: null }
size()
Number
Retorna o número total de nós residentes na árvore.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 15 , 'B' ) . insert ( 25 , 'C' ) ;
tree . size ( ) ;
// => 3
height()
Number
Retorna a distância máxima de qualquer nó folha da raiz. Se a árvore estiver vazia, -1
será retornado.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) ;
tree . height ( ) ;
// => 0
tree . insert ( 15 , 'B' ) . insert ( 25 , 'C' ) . insert ( 35 , 'D' ) ;
tree . height ( ) ;
//=> 3
inOrder(fn)
Tree
Aplica travessia em ordem (travessia em profundidade - LNR) à árvore e executa a função fn
fornecida em cada nó percorrido sem alterar a própria árvore.
fn
Function
Função a ser executada em cada nó.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . inOrder ( node => console . log ( node . key ) ) ;
// => 5
// 10
// 15
preOrder(fn)
Tree
Aplica travessia de pré-ordem (travessia em profundidade - NLR) à árvore e executa a função fn
fornecida em cada nó percorrido sem alterar a própria árvore.
fn
Function
Função a ser executada em cada nó.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . preOrder ( node => console . log ( node . key ) ) ;
// => 10
// 5
// 15
postOrder(fn)
Tree
Aplica travessia pós-ordem (travessia em profundidade - LRN) à árvore e executa a função fn
fornecida em cada nó percorrido sem alterar a própria árvore.
fn
Function
Função a ser executada em cada nó.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . postOrder ( node => console . log ( node . key ) ) ;
// => 5
// 15
// 10
outOrder(fn)
Tree
Aplica travessia fora de ordem (travessia em profundidade - RNL) à árvore e executa a função fn
fornecida em cada nó percorrido sem alterar a própria árvore.
fn
Function
Função a ser executada em cada nó.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . outOrder ( node => console . log ( node . key ) ) ;
// => 15
// 10
// 5
levelOrder(fn)
Tree
Aplica travessia de ordem de nível (travessia em largura) à árvore e executa a função fn
fornecida em cada nó percorrido sem alterar a própria árvore.
fn
Function
Função a ser executada em cada nó.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . levelOrder ( node => console . log ( node . key ) ) ;
// => 10
// 5
// 15
clear()
Tree
Muda a árvore removendo todos os nós residentes e a retorna vazia.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
//=> Tree { root: Node { left: [Node], right: [Node], key: 3, value: 'A' } }
tree . size ( ) ;
//=> 3
tree . clear ( ) ;
//=> Tree { root: null } }
tree . size ( ) ;
//=> 0
toArray()
Array<Node>
Aplica travessia em ordem à árvore e armazena cada nó percorrido em uma matriz. A matriz é retornada no final da travessia.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) . insert ( 3 , 'D' ) . insert ( 20 , 'F' ) ;
tree . toArray ( ) ;
//=> [
// Node { left: null, right: null, key: 3, value: 'D' },
// Node { left: [Node], right: null, key: 5, value: 'B' },
// Node { left: [Node], right: [Node], key: 10, value: 'A' },
// Node { left: null, right: [Node], key: 15, value: 'C' },
// Node { left: null, right: null, key: 20, value: 'F' }
// ]
toPairs()
Array<[Number, Any]>
Aplica travessia em ordem à árvore e para cada nó percorrido armazena em uma n
-tupla, onde n
o tamanho da árvore, um par ordenado/2-tupla, onde o primeiro elemento é um number
correspondente à key
do nó percorrido, e o último é um valor do tipo any
, correspondente ao value
armazenado no nó percorrido. A n
-tupla é retornada no final da travessia.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) . insert ( 3 , 'D' ) . insert ( 20 , 'F' ) ;
tree . toPairs ( ) ;
//=> [ [3, 'D'], [5, 'B'], [10, 'A'], [15, 'C'], [20, 'F'] ]
leafNodes()
Array<Node>
Aplica travessia em ordem à árvore e armazena cada nó folha percorrido (nó sem filhos) em uma matriz. A matriz é retornada no final da travessia.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . leafNodes ( ) ;
//=> [
// Node { left: null, right: null, key: 5, value: 'B' },
// Node { left: null, right: null, key: 15, value: 'C' }
// ]
fullNodes()
Array<Node>
Aplica travessia em ordem à árvore e armazena cada nó completo percorrido (nó com dois filhos não nulos) em uma matriz. A matriz é retornada no final da travessia.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . fullNodes ( ) ;
//=> [
// Node { left: [Node], right: [Node], key: 10, value: 'A' }
// ]
partialNodes()
Array<Node>
Aplica travessia em ordem à árvore e armazena cada nó parcial (nó com um filho não nulo) em uma matriz. A matriz é retornada no final da travessia.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) . insert ( 20 , 'D' ) . insert ( 3 , 'E' ) ;
tree . partialNodes ( ) ;
//=> [
// Node { left: [Node], right: null, key: 5, value: 'B' },
// Node { left: null, right: [Node], key: 15, value: 'C' }
// ]
isBalanced()
Boolean
Retorna true
se a árvore estiver balanceada em altura, o que implica que sua subárvore esquerda está balanceada, sua subárvore direita está balanceada e a diferença entre as alturas da subárvore esquerda e da subárvore direita não é maior que 1. Em qualquer outro caso, o método retorna false
.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . isBalanced ( ) ;
//=> true
tree . insert ( 20 , 'D' ) . insert ( 30 , 'E' ) ;
tree . isBalanced ( ) ;
//=> false
isComplete()
Boolean
O método retorna true
se a árvore for uma árvore de pesquisa binária completa, o que implica que todos os níveis, exceto possivelmente o último, estão completamente preenchidos e todos os nós estão o mais à esquerda possível. Em qualquer outro caso, o método retorna falso.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . isComplete ( ) ;
//=> true
tree . insert ( 3 , 'D' ) ;
tree . isComplete ( ) ;
//=> true
tree . insert ( 20 , 'E' ) ;
tree . isComplete ( ) ;
//=> false
isFull()
Boolean
O método retorna true
se todos os nós residentes na árvore forem nós folha ou nós completos. Em qualquer outro caso (grau do nó igual a 1) o método retorna false
.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . isFull ( ) ;
//=> true
tree . insert ( 8 , 'D' ) ;
tree . isFull ( ) ;
//=> false
isPerfect()
Boolean
O método retorna true
se todos os nós internos residentes na árvore forem nós completos (grau do nó igual a 2) e todos os nós folha estiverem no mesmo nível de altura. Em qualquer outro caso (grau do nó igual a 1 ou nós folha e completos são encontrados no mesmo nível de altura) o método retorna false
.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) ;
tree . isPerfect ( ) ;
//=> true
tree . insert ( 3 , 'D' ) . insert ( 7 , 'E' ) . insert ( 12 , 'F' ) . insert ( 20 , 'G' ) ;
tree . isPerfect ( ) ;
//=> true
tree . insert ( 1 , 'H' ) ;
tree . isPerfect ( ) ;
//=> false
Também disponível, junto com a classe exposta Tree
, está a classe Node
, útil principalmente para fins de teste, pois pode ser utilizada para comparar nós de árvores. A classe possui um método construtor binário, com um parâmetro key
e um value
, correspondentes à chave e ao valor armazenado na instância criada, respectivamente.
key
Number
A key
correspondente à instância do nó.
const { Node } = require ( 'binstree' ) ;
const node = new Node ( 10 , 'A' ) ;
// => { key:10, value: 'A', left: null, right: null }
node . key ;
//=> 10
value
Any
O valor que o nó contém.
const { Node } = require ( 'binstree' ) ;
const node = new Node ( 10 , 'A' ) ;
// => { key: 10, value: 'A', left: null, right: null }
node . value ;
//=> 'A'
node . value = 'B'
// => { key: 10, value: 'B', left: null, right: null }
left
Node | null
A subárvore esquerda para a qual o nó aponta.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root ;
// => { key: 10, value: 'A', left: null, right: null }
tree . root . left ;
//=> null
tree . insert ( 5 , 'B' ) . root ;
// => { key: 10, value: 'A', left: { key: 5, value: 'B', left: null, right: null } , right: null }
tree . root . left ;
//=> { key: 5, value: 'B', left: null, right: null }
right
Node | null
A subárvore certa para a qual o nó aponta.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root ;
// => { key: 10, value: 'A', left: null, right: null }
tree . root . right ;
//=> null
tree . insert ( 15 , 'B' ) . root ;
// => { key: 10, value: 'A', left: null , right: { key: 15, value: 'B', left: null, right: null } }
tree . root . right ;
//=> { key: 15, value: 'B', left: null, right: null }
children
Array<Node>
Retorna um array contatando os filhos da instância, onde o filho esquerdo, se presente, é o primeiro elemento do array, e o filho direito, se presente, é o último elemento do array.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . children ;
//=> []
tree . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) . root . children ;
// => [
// { key: 5, value: 'B', left: null , right: null },
// { key: 15, value: 'C', left: null, right: null }
// ]
degree
Number
Retorna o número de subárvores para as quais o nó aponta.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . degree ;
//=> 0
tree . insert ( 5 , 'B' ) . root . degree ;
//=> 1
tree . insert ( 15 , 'C' ) . root . degree ;
//=> 2
height()
Number
Retorna a distância máxima de qualquer nó folha da instância do nó.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 15 , 'B' ) . insert ( 25 , 'C' ) . insert ( 35 , 'D' ) ;
tree . root . height ( ) ;
//=> 3
tree . root . right . height ( ) ;
//=> 2
isFull()
Boolean
Determina se um nó é completo (tem dois filhos não nulos), retornando true
ou false
conforme apropriado.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isFull ( ) ;
//=> false
tree . insert ( 5 , 'B' ) . insert ( 15 , 'C' ) . root . isFull ( ) ;
//=> true
isInternal()
Boolean
Determina se um nó é interno (tem pelo menos um filho não nulo), retornando true
ou false
conforme apropriado.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isInternal ( ) ;
//=> false
tree . insert ( 5 , 'B' ) . root . isInternal ( ) ;
//=> true
isLeaf()
Boolean
Determina se um nó é folha (não tem filhos), retornando true
ou false
conforme apropriado.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isLeaf ( ) ;
//=> true
tree . insert ( 5 , 'B' ) . root . isLeaf ( ) ;
//=> false
isLeftPartial()
Boolean
Determina se um nó é um nó parcial esquerdo (tem apenas um filho não nulo restante), retornando true
ou false
conforme apropriado.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isLeftPartial ( ) ;
//=> false
tree . insert ( 5 , 'B' ) . root . isLeftPartial ( ) ;
//=> true
isPartial()
Boolean
Determina se um nó é parcial (tem apenas um filho não nulo), retornando true
ou false
conforme apropriado.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isPartial ( ) ;
//=> false
tree . insert ( 15 , 'B' ) . root . isPartial ( ) ;
//=> true
isRightPartial()
Boolean
Determina se um nó é um nó parcial à direita (tem apenas um filho certo não nulo), retornando true
ou false
conforme apropriado.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isRightPartial ( ) ;
//=> false
tree . insert ( 15 , 'B' ) . root . isRightPartial ( ) ;
//=> true
toPair()
[Number, Any]
Retorna um par ordenado/2 tuplas, onde o primeiro elemento é um número correspondente à key
do nó, e o último é um valor, que pode ser de qualquer tipo, correspondente ao value
armazenado no nó.
const { Node , Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
const node = new Node ( 5 , 'B' ) ;
node . toPair ( ) ;
//=> [5, 'B']
tree . insert ( 10 , 'A' ) . root . toPair ( ) ;
//=> [10, 'A']
Para obter mais informações sobre como contribuir para o projeto, leia as diretrizes de contribuição.
cd binstree
npm install
ou yarn install
npm test
ou yarn test
MIT