Add latest implementation of tree algorithm in TP6 directory
[Algorithmic_C.git] / TP6 / arbres / AVL / AVL.c
diff --git a/TP6/arbres/AVL/AVL.c b/TP6/arbres/AVL/AVL.c
new file mode 100644 (file)
index 0000000..d5f58b8
--- /dev/null
@@ -0,0 +1,288 @@
+/*****************************************************************************/
+/*                                    AVL                                   */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef int t_cle;
+
+typedef struct noeud {
+       t_cle cle;
+        int deseq; /*   deseq = hauteur du ss-abre gauche 
+                             - hauteur du ss-arbre droit */
+       struct noeud *gauche, *droit;
+        } N_AVL, *AVL;
+
+
+/*****************************************************************************/
+AVL RG(AVL a)
+{
+ AVL b;
+ b = a->droit;
+ a->droit = b->gauche;
+ b->gauche = a;
+ return b;
+}
+
+
+/*****************************************************************************/
+AVL RD(AVL a)
+{
+ AVL b;
+ b = a->gauche;
+ a->gauche = b->droit;
+ b->droit = a;
+ return b;
+}
+
+
+/*****************************************************************************/
+AVL RGD(AVL a)
+{
+ a->gauche=RG(a->gauche);
+ return(RD(a));
+}
+
+
+/*****************************************************************************/
+AVL RDG(AVL a)
+{
+ a->droit=RD(a->droit);
+ return(RG(a));
+}
+
+
+/*****************************************************************************/
+AVL insere(AVL p,int x,int *verif)
+{
+ if (p == NULL) 
+   {p = (N_AVL *)malloc(sizeof(N_AVL));
+    if (p==NULL) exit(-1);
+    p->cle = x;p->gauche = NULL;p->droit = NULL;
+    p->deseq = 0; *verif = 1;
+   }
+ else if (x == p->cle) 
+          printf("Insertion impossible ! %d est deja dans l'arbre\n",x); 
+                                
+      else if (x < p->cle) 
+               {p->gauche = insere(p->gauche,x,verif);
+               if (*verif) {/* on a insere a gauche */
+                  switch (p->deseq)
+                   {case -1 : p->deseq = 0; *verif = 0; break;
+                    case  0 : p->deseq = 1; break;
+                    case  1 : // reequilibrage
+                              if (p->gauche->deseq==1)
+                                 {// rotation droite
+                                  printf("RD pour %6d\n",p->cle);
+                                  p=RD(p);
+                                  p->deseq = p->droit->deseq = 0;
+                                  *verif = 0;
+                                 }
+                              else {/* rotation gauche droite */
+                                    printf("RGD pour %6d\n",p->cle);
+                                    p=RGD(p); 
+                                    switch (p->deseq)
+                                       {case -1 : p->droit->deseq=0;
+                                                  p->gauche->deseq=1;
+                                                  break;
+                                        case  0 : p->droit->deseq=0;
+                                                  p->gauche->deseq=0;
+                                                  break;
+                                         case  1 : p->droit->deseq=-1;
+                                                  p->gauche->deseq=0;
+                                       }                          
+                                    p->deseq=0; *verif=0;
+                              }
+                              break;
+                   }
+                              
+               }
+              }
+            else 
+              {p->droit  = insere(p->droit,x,verif);
+                if (*verif) {/* on a insere a droite */
+                  switch (p->deseq)
+                   {case  1 : p->deseq = 0; *verif = 0; break;
+                    case  0 : p->deseq = -1; break;
+                    case -1 : // reequilibrage
+                              if (p->droit->deseq==-1)
+                                 {/* rotation gauche */
+                                  printf("RG pour %6d\n",p->cle);
+                                  p=RG(p);
+                                   p->deseq = p->gauche->deseq = 0;
+                                  *verif = 0;
+                                 }
+                              else {/* rotation droite gauche */
+                                    printf("RDG pour %6d\n",p->cle);
+                                    p=RDG(p);
+                                     switch (p->deseq)
+                                       {case  1 : p->droit->deseq=-1;
+                                                  p->gauche->deseq=0;
+                                                  break;
+                                        case  0 : p->droit->deseq=0;
+                                                  p->gauche->deseq=0;
+                                                  break;
+                                         case -1 : p->droit->deseq=0;
+                                                  p->gauche->deseq=1;
+                                       }                          
+                                    p->deseq=0; *verif=0;
+                              }
+                              break;               
+                   } 
+                 }
+              }
+ return(p);                      
+}
+
+
+/*****************************************************************************/
+AVL equigauche(AVL p,int *verif) 
+/* quand on entre dans la fonction, *verif = 1 */
+{
+ switch (p->deseq)
+       {case  1 : p->deseq = 0; break;
+        case  0 : p->deseq = -1; *verif = 0; break;
+        case -1 : /* reequilibrage */
+                  if (p->droit->deseq <= 0)
+                  {/* rotation gauche */
+                   printf("RG pour %6d\n",p->cle);
+                   p = RG(p);
+                   if (p->deseq == 0) {p->gauche->deseq = -1; p->deseq = 1;
+                                       *verif=0;}
+                   else {//forcement p->deseq = -1
+                         p->deseq = p->gauche->deseq = 0; }                 
+                   }
+                 else 
+                 {/* rotation droite gauche */
+                  printf("RDG pour %6d\n",p->cle);
+                  p = RDG(p);
+                  switch (p->deseq)
+                       {case  0 : p->droit->deseq = p->gauche->deseq =0; break;
+                        case  1 : p->droit->deseq = -1; p->gauche->deseq = 0; 
+                                  break;
+                        case -1 : p->droit->deseq = 0; p->gauche->deseq = 1;
+                       }
+                  p->deseq = 0; 
+                 }
+       }
+return p;
+}
+
+
+/*****************************************************************************/
+AVL equidroit(AVL p,int *verif) // quand on entre dans la fonction, verif = 1
+{
+ switch (p->deseq)
+       {case -1 : p->deseq = 0; break;
+        case  0 : p->deseq = 1; *verif = 0; break;
+        case  1 : /* reequilibrage */
+                  if (p->gauche->deseq >= 0)
+                  {/* rotation droite */
+                   printf("RD pour %6d\n",p->cle);
+                   p = RD(p);
+                   if (p->deseq == 0) {p->droit->deseq = 1; p->deseq = -1;
+                                       *verif=0; }
+                   else {/* forcement p->deseq = 1 */
+                         p->deseq = p->droit->deseq = 0; }
+                   }
+                 else 
+                 {/* rotation gauche droite */
+                  printf("RGD pour %6d\n",p->cle);
+                  p = RGD(p);
+                  switch (p->deseq)
+                       {case  0 : p->gauche->deseq = p->droit->deseq =0; break;
+                        case  1 : p->gauche->deseq = 0; p->droit->deseq = -1; 
+                                  break;
+                        case -1 : p->gauche->deseq = 1; p->droit->deseq = 0;
+                       }
+                  p->deseq = 0; 
+                 }
+       }        
+return p;
+}
+
+
+/*****************************************************************************/
+AVL supmax(AVL p,AVL r,int *verif)
+{
+ AVL q;
+ if (r->droit == NULL) {p->cle = r->cle;
+                       q = r; /* q : l'element a supprimer par free */
+                       r = r->gauche;
+                      free(q);
+                       *verif = 1;
+                       }
+ else {r->droit = supmax(p,r->droit,verif);
+       if (*verif) r = equidroit(r,verif);
+      }
+ return r;
+}
+
+
+/*****************************************************************************/
+AVL supprime(AVL p,int x,int *verif)
+{
+ AVL q;
+
+ if (p == NULL)
+    printf( "Suppression impossible ! %d n'est pas dans l'arbre\n",x);
+    else if (x == p->cle) { /* Suppression de p */
+                          if (p->droit == NULL) {q = p; p = p->gauche;
+                                                 free(q); *verif = 1; }
+                          else if (p->gauche == NULL) {q = p; p = p->droit; 
+                                                       free(q); *verif = 1; }
+                               else {p-> gauche = supmax(p,p->gauche,verif);
+                                     if (*verif) p = equigauche(p,verif);
+                                   }
+                        }
+       else if (x < p->cle) 
+               {p->gauche = supprime(p->gauche,x,verif);
+                if (*verif) p = equigauche(p,verif);
+              }
+            else {p->droit = supprime(p->droit,x,verif);
+                  if (*verif) p = equidroit(p,verif);
+                 }
+ return p;       
+}
+
+
+/*****************************************************************************/
+void affiche_arbre(AVL p, int col)
+{
+ int i; char esp=' ';
+ if (p)
+    {affiche_arbre(p->droit,col+6);
+     for (i=0;i<col;i++) printf("%c",esp);
+     printf("%6d(%2d)\n",p->cle,p->deseq);
+     affiche_arbre(p->gauche,col+6);
+    };         
+ }
+
+
+
+/*****************************************************************************/
+main()
+ {AVL rac=NULL;
+  int x;
+  int verif;
+  do {printf("Entrez une cle: ");scanf("%d",&x);
+      if (x) {printf("Insertion de la cle %6d\n",x);
+             verif = 0;
+             rac = insere(rac,x,&verif);
+             affiche_arbre(rac,0);
+             }
+     }
+  while (x);
+
+  do {printf("Entrez une cle: ");scanf("%d",&x);
+      if (x) {printf("Suppression de la cle %6d\n",x);
+             verif = 0;
+             rac = supprime(rac,x,&verif);
+             affiche_arbre(rac,0);
+      }
+     }
+  while (x);
+ }
+/*****************************************************************************/
+