Mise à jour: voir ci-dessous pour une mise à jour sur l'inexactitude de cette opération de jointure
Voici un croquis très sommaire d'une solution possible:
Je pense que je peux avoir une solution à ce problème en utilisant un type d'arbre B + équilibré de manière aléatoire. Comme les trésors, ces arbres ont une représentation unique. Contrairement aux treaps, ils stockent plusieurs clés plusieurs fois. Il pourrait être possible de résoudre ce problème en utilisant une astuce des "Arbres de recherche biaisés" de Bent et al. Consistant à stocker chaque clé uniquement au niveau le plus élevé (c'est-à-dire le plus proche de la racine) dans lequel elle apparaît)
Un arbre pour un ensemble ordonné de valeurs uniques est créé en associant d'abord chaque valeur à un flux de bits, similaire à la façon dont chaque valeur dans un treap est associée à une priorité. Chaque nœud de l'arborescence contient à la fois une clé et un flux binaire. Les nœuds non foliaires contiennent, en outre, un nombre naturel indiquant la hauteur de l'arbre enraciné à ce nœud. Les nœuds internes peuvent avoir un nombre d'enfants différent de zéro. Comme les arbres B +, chaque chemin non auto-intersecté de la racine à une feuille a la même longueur.
Chaque nœud interne contient (comme dans les arbres B +) la plus grande clé k de ses feuilles descendantes. Chacun contient également un nombre naturel i indiquant la hauteur de l'arbre enraciné en v , et le flux de bits associé à k à partir du i + 1 ème bit. Si chaque clé de l'arborescence enracinée en v a le même premier bit dans son flux binaire, chaque enfant de v est une feuille et i est 1 . Sinon, les enfants de v sont des nœuds internes qui ont tous le même i ème bit dans le flux binaire associé à leur clé.vkivki+1vvi1vi
Pour créer une arborescence à partir d'une liste triée de clés avec des flux binaires associés, collectez d'abord les clés en groupes contigus en fonction du premier bit de leurs flux. Pour chacun de ces groupes, créez un parent avec la clé et le flux binaire de la plus grande clé du groupe, mais en supprimant le premier bit du flux. Effectuez maintenant la même procédure de regroupement sur les nouveaux parents pour créer des grands-parents. Continuez jusqu'à ce qu'il ne reste qu'un nœud; c'est la racine de l'arbre.
La liste suivante de clés et (début de) flux binaires est représentée par l'arborescence en dessous. Dans les préfixes de flux binaire, un '.' signifie tout. C'est-à-dire que tout flux binaire pour la clé A avec un 0 en premier lieu produit le même arbre que n'importe quel autre, en supposant qu'aucun flux binaire d'une autre clé ne soit différent.
A 0...
B 00..
C 10..
D 0...
E 0011
F 1...
G 110.
H 0001
____H____
/ \
E H
| / \
__E__ G H
/ | \ | |
B C E G H
/ \ | / \ / \ |
A B C D E F G H
Chaque enfant d'un nœud interne particulier a le même bit en premier lieu de son flux binaire. C'est ce qu'on appelle la "couleur" du parent - 0 est rouge, 1 est vert. L'enfant a une "saveur" en fonction du premier bit de son flux binaire - 0 est cerise, 1 est menthe. Les feuilles ont des saveurs, mais pas de couleur. Par définition, un nœud cerise ne peut pas avoir de parent vert et un nœud menthe ne peut pas avoir de parent rouge.
n21−n (n−1i−1)(n+1)/2n≥2≤34nO(lgn)
Pour joindre deux arbres de même hauteur, vérifiez d'abord si leurs racines sont de la même couleur. Si c'est le cas, coupez de la racine gauche son enfant le plus à droite et de la racine droite son enfant le plus à gauche, puis joignez récursivement ces deux arbres. Le résultat sera un arbre de la même hauteur ou un plus grand car les arbres ont la même saveur (voir ci-dessous). Si le résultat de la jonction récursive des deux arbres a la même hauteur que les deux enfants coupés, faites-en l'enfant du milieu d'une racine avec les autres enfants de la racine gauche devant elle et les autres enfants de la racine droite après elle. S'il est plus grand de 1, faites de ses enfants les enfants du milieu d'une racine avec les autres enfants de la racine gauche avant et les autres enfants de la racine droite après elle. Si les racines ont des couleurs différentes, vérifiez si elles ont la même saveur. S'ils le font, donnez-leur un nouveau parent avec la clé et le flux binaire de la racine droite, élidant son premier bit. Si ce n'est pas le cas, donnez à chaque racine un nouveau parent avec la clé et le flux binaire de l'ancienne racine (en supprimant chaque premier bit), puis joignez récursivement ces arbres.
1/21/2O(1)1/4, et les appels récursifs ultérieurs sont toujours sur des arbres de couleurs différentes, donc la même analyse s'applique.
1/2O(1)
O(1)
a 01110
b 110..
c 10...
d 00000
L'arbre fait par [a,b]
a une hauteur 2, l'arbre fait par [c,d]
a une hauteur 2, et l'arbre fait par joinEqual (tree [a,b]) (tree [c,d])
a une hauteur 3. Cependant, l'arbre fait par [a,b,c,d]
a une hauteur 5.
Voici le code que j'ai utilisé pour trouver cette erreur .