Cette page essaie de résumer le cours d'algorithmique avancé avec les éléments principaux
typedef struct node {
int value;
struct node *leftSubtree, *rightSubtree;
} Node, *BinaryTree;
1) Recherche le noeud n où se toruve k
2) Si n est une feuille, supprimer n
3) Si n n'a pas de fils gauche
-> Recoller le fils droit
4) Si n n'a pas de fils droit
-> Recoller le fils gauche
5) Sinon
a) Aller chercher le max à gauche de n
b) Le supprimer
c) remplacer la valeur de n par le max
Nom | Définition |
---|---|
Arbre équilibré | |Hauteur gauche - Hauteur droite| est controllée |
Un arbre est rouge noir si :
typedef struct rbnode {
int value;
int color;
struct rbnode *leftSubtree, *rightSubtree;
struct rbnode *father ;
} RBNode, *RBBinaryTree;
1) On insère le noeud comme un ABR classique (il aura la couleur rouge)
2) On regarde si la racine est rouge -> On la change à noire
3) On rééquilibre le noeud que nous venons d'ajouter
Le noeud que nous devons rééquilibrer est noté n
1) On regarde si le parent de n est rouge et si n est rouge
a) Si l'oncle de n est rouge :
aa) L'oncle devient noir
ab) Le parent de n devent noir
ac) Le parent du parent de n devient rouge
ad) On rééquilibre le parent du parent de n
b) Si l'oncle de n est noir
ba) Si le noeud inséré est full à gauche ou full à droite
baa) Si le noeud inséré est full à gauche
On fait une rotation droite à partir du parent du parent de n
baa) Si le noeud inséré est full à droite
On fait une rotation gauche à partir du parent du parent de n
bb) Sinon
bba) Si le noeud inséré est gauche puis droite
On fait une rotation gauche à partir du parent de n
On rééquilibre le fils gauche de n
bbb) Si le noeud inséré est droite puis gauche
On fait une rotation droite à partir du parent de n
On rééquilibre le fils droit de n
Exemples de rééquilibrage de noeud dans le cours
Rotation :
Comme un ABR classique mais on ajoute de l'aléa aux algorithmes d'insertion et de suppression pour éviter les arbres dégénérés
typedef struct node {
int value;
struct node *leftSubtree, *rightSubtree;
int size;
} Node, *BinaryTree;
K est le nombre à partir duquel on veut splitter notre arbre.
3 manières de splitter :
L'insertion utilise la fonction split et se déroule comme suit :
Insertion(arbre, k)
taille <- la taille de l'arbre (le nombre de noeud)
hasard <- calcul d'un nombre au hasard entre 0 et 1
si hasard < 1/taille + 1 alors
on insère k à la racine de arbre
arbreGauche, arbreDroit = split(arbre, k)
on ajoute k à la racine de arbreDroit
sinon
si k > arbre.valeur
Insertion(arbre.partieDroite, k)
sinon
Insertion(arbre.partieGauche, k)
fin
fin
Nous voulons join l'arbre vert et l'arbre rouge suivant :
On tire p, un nombre au hasard entre 1 et taille de l'arbre vert + taille de l'arbre rouge
Si p < taille a, la fonction retourne
Si p > taille a, la fonction retourne
Pour supprimer, on utilise cette fonction :
Suppression(Arbre A, k)
Si racine(A) = k
Retourne Join(Arbre.arbreGauche, Arbre.arbreDroit)
Sinon
Si racine(A) < k
copie = copie(a)
copie.arbreDroit = supprimer(copie.arbreDroit, k)
retourne copie
Sinon
copie = copie(a)
copie.arbreGauche = supprimer(copie.arbreGauche, k)
retourne copie
Fin
Fin
Le Master theorem permet de factoriser une complexité. Elle existe en 3 partie.
Si on a une complexité de cette forme :
c(\color{red}{m}\color{black}) = \color{blue}{a} \color{black}\times c (\color{red}{m}\color{black} / \color{green}{b}\color{black}) + f(\color{red}{m}\color{black})
Alors il est possible de factoriser la complexité en fonction de KaTeX:f
Si KaTeX:f
croit lentement : KaTeX:f(\color{red}m\color{black}) \text{est négligeable par rapport à}\\ \color{red}m\color{black}^{log_{\color{blue}b}^{\color{green}a\color{black}}}
Alors il est possible de factoriser c(m) de cette façon :
c(\color{red}m\color{black}) = o(\color{red}m\color{black}^{log_{\color{blue}b}^{\color{green}a\color{black}}})
Si KaTeX:f
croit assez rapidement : KaTeX:f(\color{red}m\color{black}) = o(\color{red}m\color{black}^{log_{\color{blue}b}^{\color{green}a\color{black}}})
Alors il est possible de factoriser c(m) de cette façon :
c(\color{red}m\color{black}) = o(\color{red}m\color{black}^{log_{\color{blue}b}^{\color{green}a\color{black}}} \times log(\color{red}m\color{black}))
Si KaTeX:f
croit rapidement : KaTeX:\color{red}m\color{black}^{log_{\color{blue}b}^{\color{green}a\color{black}}} \text{est négligeable par rapport à}\\f(\color{red}m\color{black})
Alors il est possible de factoriser c(m) de cette façon :
c(\color{red}m\color{black}) = o(f(\color{red}m\color{black}))
On peut partitionner des sommets en classe d'équivalence si il existe des relations d'équivalences entre ses membres.
Dans un graphe non-orienté, si il est possible d'aller d'un élément à un autre, alors il y a une relation d'équivalence entre ses membres
Dans un graphe orienté, si il est possible d'aller d'un élément à un autre et de revenir sur l'élément de départ, alors il y a une relation d'équivalence entre ses membres. Ils sont même fortement connexe
Pattern | Description |
---|---|
Arbre | Graphe non orienté, connexe et sans cycle |
Arbre enraciné | Arbre avec un sommet distingué (racine) |
Forêt | Graphe non orienté où chaque composante connexe est un arbre |
Pour montrer les connexions entre les différents membres d'un graphe, on utilise une matrice d'adjacence :
La matrice d'adjacence suit le sens d'un graphe orienté
De la même manière, si on utilise des distances, on les ajoute dans la matrice :
On utilise une File
Ici :
Parcours_Largeur:
Pour chaque sommet u appartenant à v
Marquer u en rouge
F = File vide
Marquer s en orange
Ajouter s à F
TantQue F n'est pas vide
u = défiler(F)
Marquer u en vert
Pour tout voisin v de u
Si couleur(v) == rouge
Ajouter v à F
Marquer v en orange
On utilise une pile
Ici :
Parcours_profondeur
Pour chaque sommet u appartenant à v
Marquer u en rrouge
P = Pile vide
Marquer s en orange
Ajouter s à P
TantQue P n'est pas vide
Si Sommet(P) a un voisin rouge v
ajouter v à P
Mettre v à orange
Sinon
u = dépiler P
Mettre u à vert