Implémentation ES6 de la structure de données de l'arbre de recherche binaire avec prise en charge de TypeScript.
Consultez les directives de contribution pour en savoir plus sur la façon de traduire ce document dans davantage de langues.
yarn add binstree
npm install binstree
Un arbre de recherche binaire est une structure de données d'arbre binaire enraciné, dont les nœuds contiennent une key
unique et une value
associée, et pointent vers deux sous-arbres left
et right
distincts. L'arbre satisfait à la propriété de recherche binaire, donc la clé dans chaque nœud est supérieure à n'importe quelle clé stockée dans le sous-arbre de gauche et inférieure à n'importe quelle clé stockée dans le sous-arbre de droite. Résultat imminent de ce principe, les opérations sur les arbres en bénéficient grandement, puisqu'en moyenne chaque comparaison clé permet aux opérations de sauter environ la moitié de l'arbre, de sorte que chaque insertion, suppression ou recherche prend un temps proportionnel au logarithme du nombre de nœuds. stockés dans l’arbre.
Binstree expose une API chaînable, qui peut être utilisée via une syntaxe simple et minimale, vous permettant de combiner efficacement des méthodes.
Des exemples d'utilisation peuvent également être trouvés dans le répertoire 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
Mute l'arborescence en insérant un nouveau nœud à l'emplacement approprié.
key
Number
Il peut s'agir de n'importe quel nombre correspondant à la key
du nœud créé. Chaque nœud possède sa propre key
unique.
value
Any
Il peut s'agir de n'importe quelle valeur qui sera stockée dans le nœud créé.
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
Renvoie le nœud racine de l'arborescence. Si l'arborescence est vide, null
est renvoyé.
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
Détermine si l'arborescence est vide, renvoyant true
ou false
selon le cas.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) ;
tree . isEmpty ( ) ;
// => false
remove(key)
Tree
Mute l'arborescence en supprimant le nœud correspondant à l'argument key
.
key
Number
Il peut s'agir de n'importe quel nombre correspondant à la key
d'un nœud existant.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) ;
tree . remove ( 10 ) ;
//=> Tree { root: null }
includes(key)
Boolean
Détermine si l'arborescence comprend un nœud avec une certaine key
, renvoyant true
ou false
selon le cas.
key
Number
key
de nœud à rechercher.
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
Détermine si l'arborescence comprend un nœud avec une certaine key
, renvoyant le nœud ciblé ou null
selon le cas.
key
Number
key
de nœud à rechercher.
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
Renvoie le nœud le plus à gauche de l'arborescence, donc le nœud correspondant à la key
minimale.
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
Renvoie le nœud le plus à droite de l'arborescence, donc le nœud correspondant à la key
maximale.
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
Renvoie le nombre total de nœuds résidant dans l'arborescence.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . insert ( 15 , 'B' ) . insert ( 25 , 'C' ) ;
tree . size ( ) ;
// => 3
height()
Number
Renvoie la distance maximale de tout nœud feuille à la racine. Si l'arborescence est vide, -1
est renvoyé.
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
Applique un parcours dans l'ordre (parcours en profondeur en premier - LNR) à l'arbre et exécute la fonction fn
fournie sur chaque nœud traversé sans muter l'arbre lui-même.
fn
Function
Fonction à exécuter sur chaque nœud.
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
Applique un parcours de pré-ordre (parcours en profondeur en premier - NLR) à l'arbre et exécute la fonction fn
fournie sur chaque nœud traversé sans muter l'arbre lui-même.
fn
Function
Fonction à exécuter sur chaque nœud.
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
Applique un parcours post-ordre (parcours en profondeur en premier - LRN) à l'arbre et exécute la fonction fn
fournie sur chaque nœud traversé sans muter l'arbre lui-même.
fn
Function
Fonction à exécuter sur chaque nœud.
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
Applique un parcours dans le désordre (parcours en profondeur en premier - RNL) à l'arbre et exécute la fonction fn
fournie sur chaque nœud traversé sans muter l'arbre lui-même.
fn
Function
Fonction à exécuter sur chaque nœud.
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
Applique un parcours par ordre de niveau (parcours en largeur d'abord) à l'arbre et exécute la fonction fn
fournie sur chaque nœud traversé sans muter l'arbre lui-même.
fn
Function
Fonction à exécuter sur chaque nœud.
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
Mute l'arborescence en supprimant tous les nœuds résidents et le renvoie vide.
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>
Applique un parcours dans l'ordre à l'arborescence et stocke chaque nœud traversé dans un tableau. Le tableau est renvoyé à la fin du parcours.
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]>
Applique un parcours dans l'ordre à l'arbre et, pour chaque nœud parcouru, stocke dans un n
-tuple, où n
la taille de l'arbre, une paire ordonnée/2-tuple, où le premier élément est un number
correspondant à la key
du nœud traversé, et la dernière est une valeur de type any
, correspondant à la value
stockée dans le nœud traversé. Le n
-tuple est renvoyé à la fin du parcours.
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>
Applique un parcours dans l'ordre à l'arborescence et stocke chaque nœud feuille traversé (nœud sans enfants) dans un tableau. Le tableau est renvoyé à la fin du parcours.
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>
Applique un parcours dans l'ordre à l'arborescence et stocke chaque nœud complet traversé (nœud avec deux enfants non nuls) dans un tableau. Le tableau est renvoyé à la fin du parcours.
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>
Applique un parcours dans l'ordre à l'arborescence et stocke chaque nœud partiel (nœud avec un enfant non nul) dans un tableau. Le tableau est renvoyé à la fin du parcours.
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
Renvoie true
si l'arbre est équilibré en hauteur, ce qui implique que son sous-arbre gauche est équilibré, son sous-arbre droit est équilibré et que la différence entre les hauteurs du sous-arbre gauche et du sous-arbre droit n'est pas supérieure à 1. dans tous les autres cas, la méthode renvoie 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
La méthode renvoie true
si l'arbre est un arbre de recherche binaire complet, ce qui implique que chaque niveau, sauf éventuellement le dernier, est complètement rempli et que tous les nœuds sont aussi à gauche que possible. Dans tous les autres cas, la méthode renvoie false.
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
La méthode renvoie true
si tous les nœuds résidant dans l'arborescence sont soit des nœuds feuilles, soit des nœuds complets. Dans tous les autres cas (degré de nœud égal à 1), la méthode renvoie 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
La méthode renvoie true
si tous les nœuds internes résidant dans l'arborescence sont des nœuds complets (degré de nœud égal à 2) et que tous les nœuds feuilles sont au même niveau de hauteur. Dans tous les autres cas (degré de nœud égal à 1 ou les nœuds feuille et complets se trouvent au même niveau de hauteur), la méthode renvoie 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
La classe Node est également disponible, outre la classe exposée Tree
, la classe Node
, principalement utile à des fins de test, car elle peut être utilisée pour comparer les nœuds d'arbre. La classe possède une méthode de constructeur binaire, avec une key
et un paramètre value
, correspondant respectivement à la clé et à la valeur stockées dans l'instance créée.
key
Number
La key
correspondant à l'instance de nœud.
const { Node } = require ( 'binstree' ) ;
const node = new Node ( 10 , 'A' ) ;
// => { key:10, value: 'A', left: null, right: null }
node . key ;
//=> 10
value
Any
La valeur que contient le nœud.
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
Le sous-arbre gauche vers lequel pointe le nœud.
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
Le sous-arbre droit vers lequel pointe le nœud.
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>
Renvoie un tableau contactant les enfants de l'instance, où l'enfant de gauche, s'il est présent, est le premier élément du tableau, et l'enfant de droite, s'il est présent, est le dernier élément du tableau.
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
Renvoie le nombre de sous-arbres vers lesquels pointe le nœud.
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
Renvoie la distance maximale de tout nœud feuille par rapport à l'instance de nœud.
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
Détermine si un nœud est un nœud complet (a deux enfants non nuls), renvoyant true
ou false
selon le cas.
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
Détermine si un nœud est un nœud interne (a au moins un enfant non nul), renvoyant true
ou false
selon le cas.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isInternal ( ) ;
//=> false
tree . insert ( 5 , 'B' ) . root . isInternal ( ) ;
//=> true
isLeaf()
Boolean
Détermine si un nœud est un nœud feuille (n'a pas d'enfants), renvoyant true
ou false
selon le cas.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isLeaf ( ) ;
//=> true
tree . insert ( 5 , 'B' ) . root . isLeaf ( ) ;
//=> false
isLeftPartial()
Boolean
Détermine si un nœud est un nœud partiel gauche (a un seul enfant gauche non nul), renvoyant true
ou false
selon le cas.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isLeftPartial ( ) ;
//=> false
tree . insert ( 5 , 'B' ) . root . isLeftPartial ( ) ;
//=> true
isPartial()
Boolean
Détermine si un nœud est un nœud partiel (a un seul enfant non nul), renvoyant true
ou false
selon le cas.
const { Tree } = require ( 'binstree' ) ;
const tree = new Tree ( ) ;
tree . insert ( 10 , 'A' ) . root . isPartial ( ) ;
//=> false
tree . insert ( 15 , 'B' ) . root . isPartial ( ) ;
//=> true
isRightPartial()
Boolean
Détermine si un nœud est un nœud partiel droit (a un seul enfant droit non nul), renvoyant true
ou false
selon le cas.
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]
Renvoie une paire ordonnée/2-tuple, où le premier élément est un nombre correspondant à la key
du nœud, et le dernier est une valeur, qui peut être de n'importe quel type, correspondant à la value
stockée dans le nœud.
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']
Pour plus d'informations sur la façon de contribuer au projet, veuillez lire les directives de contribution.
cd binstree
npm install
ou yarn install
npm test
ou yarn test
MIT