Implementación ES6 de la estructura de datos del árbol de búsqueda binaria con soporte TypeScript.
Visite las pautas de contribución para obtener más información sobre cómo traducir este documento a más idiomas.
yarn add binstree
npm install binstree
Un árbol de búsqueda binario es una estructura de datos de árbol binario enraizado, cuyos nodos contienen una key
única y un value
asociado, y apuntan a dos subárboles left
y right
distinguidos. El árbol satisface la propiedad de búsqueda binaria, por lo que la clave en cada nodo es mayor que cualquier clave almacenada en el subárbol izquierdo y menor que cualquier clave almacenada en el subárbol derecho. Como resultado inminente de este principio, las operaciones de árbol se ven enormemente beneficiadas, ya que en promedio cada comparación de claves permite que las operaciones omitan aproximadamente la mitad del árbol, de modo que cada inserción, eliminación o búsqueda toma un tiempo proporcional al logaritmo del número de nodos. almacenado en el árbol.
Binstree expone una API encadenable, que se puede utilizar mediante una sintaxis simple y mínima, lo que le permite combinar métodos de manera efectiva.
También se pueden encontrar ejemplos de uso en el directorio 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
Muta el árbol insertando un nuevo nodo en la ubicación adecuada.
key
Number
Puede ser cualquier número que corresponda a la key
del nodo creado. Cada nodo tiene su propia key
única.
value
Any
Puede ser cualquier valor que se almacenará en el nodo creado.
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
Devuelve el nodo raíz del árbol. Si el árbol está vacío se devuelve 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 si el árbol está vacío y devuelve true
o false
según corresponda.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) ;
tree . isEmpty ( ) ;
// => false
remove(key)
Tree
Muta el árbol eliminando el nodo correspondiente al argumento key
.
key
Number
Puede ser cualquier número que corresponda a la key
de un nodo existente.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) ;
tree . remove ( 10 ) ;
//=> Tree { root: null }
includes(key)
Boolean
Determina si el árbol incluye un nodo con una key
determinada, devolviendo true
o false
según corresponda.
key
Number
key
de nodo a buscar.
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 si el árbol incluye un nodo con una key
determinada y devuelve el nodo objetivo o null
según corresponda.
key
Number
key
de nodo a buscar.
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
Devuelve el nodo más a la izquierda del árbol, por lo tanto, el nodo correspondiente a la 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
Devuelve el nodo más a la derecha del árbol, por lo tanto, el nodo correspondiente a la 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
Devuelve el número total de nodos que residen en el árbol.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 15 , 'B' ) . insert ( 25 , 'C' ) ;
tree . size ( ) ;
// => 3
height()
Number
Devuelve la distancia máxima de cualquier nodo hoja desde la raíz. Si el árbol está vacío, se devuelve -1
.
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 un recorrido en orden (recorrido en profundidad primero - LNR) al árbol y ejecuta la función fn
proporcionada en cada nodo atravesado sin mutar el árbol en sí.
fn
Function
Función a ejecutar en cada nodo.
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 un recorrido de pedido previo (recorrido en profundidad primero - NLR) al árbol y ejecuta la función fn
proporcionada en cada nodo atravesado sin mutar el árbol en sí.
fn
Function
Función a ejecutar en cada nodo.
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 un recorrido posterior al orden (recorrido en profundidad primero - LRN) al árbol y ejecuta la función fn
proporcionada en cada nodo atravesado sin mutar el árbol en sí.
fn
Function
Función a ejecutar en cada nodo.
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 un recorrido fuera de orden (recorrido en profundidad primero - RNL) al árbol y ejecuta la función fn
proporcionada en cada nodo atravesado sin mutar el árbol en sí.
fn
Function
Función a ejecutar en cada nodo.
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 un recorrido de orden de nivel (recorrido de ancho primero) al árbol y ejecuta la función fn
proporcionada en cada nodo atravesado sin mutar el árbol en sí.
fn
Function
Función a ejecutar en cada nodo.
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
Muta el árbol eliminando todos los nodos residentes y lo devuelve vacío.
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 un recorrido en orden al árbol y almacena cada nodo atravesado en una matriz. La matriz se devuelve al final del recorrido.
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 el recorrido en orden al árbol y para cada nodo atravesado se almacena en una n
-tupla, donde n
el tamaño del árbol, un par ordenado/2-tupla, donde el primer elemento es un number
correspondiente a la key
del nodo atravesado, y el último es un valor de tipo any
, correspondiente al value
almacenado en el nodo atravesado. La n
-tupla se devuelve al final del recorrido.
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 un recorrido en orden al árbol y almacena cada nodo de hoja atravesado (nodo sin hijos) en una matriz. La matriz se devuelve al final del recorrido.
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 el recorrido en orden al árbol y almacena cada nodo completo atravesado (nodo con dos hijos no nulos) en una matriz. La matriz se devuelve al final del recorrido.
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 un recorrido en orden al árbol y almacena cada nodo parcial (nodo con un hijo no nulo) en una matriz. La matriz se devuelve al final del recorrido.
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
Devuelve true
si el árbol tiene altura equilibrada, lo que implica que su subárbol izquierdo está equilibrado, su subárbol derecho está equilibrado y la diferencia entre las alturas del subárbol izquierdo y el subárbol derecho no es mayor que 1. En cualquier otro caso, el método devuelve 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
El método devuelve true
si el árbol es un árbol de búsqueda binario completo, lo que implica que cada nivel, excepto posiblemente el último, está completamente lleno y todos los nodos están lo más a la izquierda posible. En cualquier otro caso, el método devuelve 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
El método devuelve true
si todos los nodos que residen en el árbol son nodos hoja o nodos completos. En cualquier otro caso (grado de nodo igual a 1) el método devuelve 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
El método devuelve true
si todos los nodos internos que residen en el árbol son nodos completos (grado de nodo igual a 2) y todos los nodos de hoja están al mismo nivel de altura. En cualquier otro caso (el grado del nodo es igual a 1 o los nodos hoja y completos se encuentran en el mismo nivel de altura), el método devuelve 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
También está disponible, junto con la clase expuesta Tree
, la clase Node
, útil principalmente para fines de prueba, ya que se puede utilizar para comparar nodos de árbol. La clase tiene un método constructor binario, con un parámetro key
y un value
, correspondientes a la clave y el valor almacenados en la instancia creada, respectivamente.
key
Number
La key
correspondiente a la instancia del nodo.
const { Node } = require ( 'binstree' ) ;
const node = new Node ( 10 , 'A' ) ;
// => { key:10, value: 'A', left: null, right: null }
node . key ;
//=> 10
value
Any
El valor que contiene el nodo.
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
El subárbol izquierdo al que apunta el nodo.
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
El subárbol derecho al que apunta el nodo.
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>
Devuelve una matriz que contacta a los hijos de la instancia, donde el hijo izquierdo, si está presente, es el primer elemento de la matriz, y el hijo derecho, si está presente, es el último elemento de la matriz.
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
Devuelve el número de subárboles a los que apunta el nodo.
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
Devuelve la distancia máxima de cualquier nodo hoja desde la instancia del nodo.
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 si un nodo es un nodo completo (tiene dos hijos no nulos) y devuelve true
o false
según corresponda.
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 si un nodo es un nodo interno (tiene al menos un hijo no nulo) y devuelve true
o false
según corresponda.
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 si un nodo es un nodo hoja (no tiene hijos), y devuelve true
o false
según corresponda.
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 si un nodo es un nodo parcial izquierdo (solo tiene un hijo no nulo) y devuelve true
o false
según corresponda.
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 si un nodo es un nodo parcial (tiene un solo hijo no nulo) y devuelve true
o false
según corresponda.
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 si un nodo es un nodo parcial derecho (tiene un solo hijo derecho no nulo) y devuelve true
o false
según corresponda.
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]
Devuelve un par ordenado/2-tupla, donde el primer elemento es un número correspondiente a la key
del nodo, y el último es un valor, que puede ser de cualquier tipo, correspondiente al value
almacenado en el nodo.
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 obtener más información sobre cómo contribuir al proyecto, lea las pautas de contribución.
cd binstree
npm install
o yarn install
npm test
o yarn test
MIT