Définissons une fonction split(T,v)
qui prend dans un arbre, T
et une valeur de scission à, v
. Supposons que chaque nœud de l'arborescence stocke son enfant gauche et son enfant droit en plus de la valeur de ce nœud. Utilisez l'algorithme suivant:
Nous vérifions d'abord si l'arbre d'entrée est simplement une feuille ou non.
Si T
n'est pas une feuille, comparez la valeur de son nœud racine v'
avec v
.
Si c'est v' < v
alors récursivement appeler split sur le sous-arbre gauche. Stockez les valeurs de l'appel récursif sous L'
(arborescence renvoyée à gauche), R'
(renvoyée arborescence à droite) et r
(type d'option indiqué si la valeur a v
été trouvée ou non). Construisez le nouvel arbre de droite newR = Node(R',v',R)
, et revenez (L',r,newR)
.
Sinon, v' > v
appelez alors récursivement split sur le sous-arbre droit. Stockez les valeurs de l'appel récursif sous L'
(arborescence renvoyée à gauche), R'
(renvoyée arborescence à droite) et r
(type d'option indiqué si la valeur a v
été trouvée ou non). Construisez le nouvel arbre de gauche newL = Node(L',v',L)
, et revenez (newL,r,R')
.
Sinon v' = v
, revenez L, SOME(v), R
.
Si T
est une feuille, nous devons avoir atteint la racine de l'arbre sans trouver la valeur d'entrée v à diviser. Revenez que vous n'avez pas trouvé la feuille en repassant NONE
.
Pourquoi est-ce logarithmique? Eh bien, vous ne traversez qu'un seul chemin de la racine à la feuille de l'arbre, tout au plus. Nous pouvons facilement reconstruire des nœuds en temps constant car nous ne faisons que réaffecter des références (dans un langage impératif) ou réaffecter des valeurs qui prennent un temps constant à générer (dans un langage fonctionnel ).O(logn)O(logn)
Voici le code correspondant à l'algorithme. C'est écrit en SML, mais je serais prêt à clarifier ce que quelque chose signifie dans les commentaires.
fun split(T,v) =
case T of
Leaf => (Leaf, NONE, Leaf)
| Node(L,v,R) =>
case compare(v, v') of
LESS =>
let
val (L',r,R') = split(L,k)
in
(L',r,Node(R',r,R))
end
| GREATER =>
let
val (L',r,R') = split(R,k)
in
(Node(L',v',L),r,R')
end
| EQUAL => (L, SOME(v), R)
Consultez ce document pour plus de détails. Il fournit une explication plus approfondie de ce qui précède.