web-dev-qa-db-fra.com

Explication de l'implémentation arborescente rouge-noir de TreeMap dans JAVA

Je parcourais le code source de TreeMap en Java . Selon Java doc:

Une implémentation NavigableMap basée sur un arbre rouge-noir. La carte est triée selon l'ordre naturel de ses clés, ou par un comparateur fourni au moment de la création de la carte, selon le constructeur utilisé.

Cette implémentation garantit un coût de journalisation (n) garanti pour les opérations containsKey, get, put et remove. Les algorithmes sont des adaptations de ceux de l'introduction aux algorithmes de Cormen, Leiserson et Rivest.

Dans le code source, j'ai trouvé qu'une entrée de classe interne était utilisée comme nœud .

static final class Entry<K,V> implements Map.Entry<K,V> {
        K key;
        V value;
        Entry<K,V> left = null;
        Entry<K,V> right = null;
        Entry<K,V> parent;
        boolean color = BLACK;
        ....

Quant à la définition de arbre rouge-noir . De Wikipédia, j'ai trouvé:

Un arbre rouge-noir est un type d'arbre de recherche binaire à équilibrage automatique, une structure de données utilisée en informatique.

L'auto-équilibrage est fourni en peignant chaque nœud avec l'une des deux couleurs (celles-ci sont généralement appelées `` rouge '' et `` noir '', d'où le nom des arbres) de telle manière que l'arbre peint résultant satisfait certaines propriétés qui ne '' t lui permettre de devenir considérablement déséquilibré. Lorsque l'arbre est modifié, le nouvel arbre est ensuite réorganisé et repeint pour restaurer les propriétés colorantes. Les propriétés sont conçues de telle manière que ce réarrangement et cette recoloration puissent être effectués efficacement.

J'ai essayé d'analyser le code souce mais je ne comprenais pas ce qui suit:

  1. Supposons que j'ai déjà deux clés "C" et "E" dans l'arborescence, puis j'ajoute "D". Comment les nœuds seront organisés (en utilisant l'ordre naturel).

  2. Comment l'auto-équilibrage de Tree est implémenté dans le code source Java.

J'ai essayé de rechercher l'implémentation détaillée de TreeMap, mais je n'ai trouvé aucun article tel que article suivant que j'ai trouvé pour HashMap

Depuis hier, je suis accroché à cet arbre :( quelqu'un peut-il m'aider à descendre ...

28
Zeeshan
  1. Le but de TreeMap est d'avoir un arbre de clés où les clés inférieures à la clé du parent sont à gauche et les clés supérieures à la clé du parent sont à droite. Donc, si vous ajoutez C, puis E, vous aurez cet arbre:

    C
     \
      E
    

    Si vous ajoutez ensuite D, vous aurez initialement:

    C
     \
      E
     /
    D
    

    Mais cet arbre est déséquilibré et les recherches seraient donc plus lentes. Ainsi, l'arbre est rééquilibré. Après l'équilibrage, l'arbre devient maintenant beaucoup plus efficace:

    C                     C
     \        rotate       \         rotate         D
      E   --- right --->    D    ---  left --->    / \
     /        around         \       around       C   E
    D           E             E        D
    
  2. Le rééquilibrage a lieu à l'intérieur de la méthode fixAfterInsertion(), qui vérifie si les propriétés rouge-noir de l'arborescence sont toujours conservées après l'insertion. Et, si ce n'est pas le cas, il rééquilibre l'arborescence en exécutant rotateLeft() ou rotateRight() sur la branche incriminée pour rétablir l'équilibre. Ensuite, il remonte dans l'arbre et vérifie l'équilibre et ainsi de suite jusqu'à ce qu'il atteigne le nœud racine.

Il existe plusieurs ressources sur Internet qui expliquent en détail les arbres rouges et noirs. Mais, je pense que la meilleure façon de comprendre le processus est de suivre un tutoriel animé comme celui-ci: http://www.csanimated.com/animation.php?t=Red-black_tree

Il n'y a rien de particulier dans l'implémentation TreeMap de RBT. Il suit de près le pseudocode donné dans le livre de CLRS (Cormen, Leiserson, Rivest et Stein), ce que font 99% des implémentations autour.

45
EmirCalabuch