Merge branch 'master' of https://codefirst.iut.uca.fr/git/antoine.perederii/IUT
@ -0,0 +1,34 @@
|
|||||||
|
# CC : le compilateur à utiliser
|
||||||
|
CC=clang
|
||||||
|
|
||||||
|
# CFLAGS : les options de compilation
|
||||||
|
CFLAGS=-Wall
|
||||||
|
|
||||||
|
# Les fichiers sources : tous les fichiers présents dans src/
|
||||||
|
SRC=$(wildcard src/*.c)
|
||||||
|
|
||||||
|
# Les fichiers objets (.o)
|
||||||
|
OBJ=$(patsubst src/%.c,obj/%.o,$(SRC))
|
||||||
|
|
||||||
|
# Le répertoire où sera générée la documentation Doxygen
|
||||||
|
DOXYGEN_OUTPUT_DIR=docs
|
||||||
|
|
||||||
|
# Édition des liens : génération de l'exécutable à partir des .o
|
||||||
|
bin/exe: $(OBJ)
|
||||||
|
$(CC) $(OBJ) -o $@
|
||||||
|
|
||||||
|
# Génération des .o à partir des .c correspondants
|
||||||
|
obj/%.o: src/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Génération de la documentation Doxygen
|
||||||
|
doxygen:
|
||||||
|
doxygen Doxyfile
|
||||||
|
|
||||||
|
# Exécution du programme avec Valgrind
|
||||||
|
valgrind: bin/exe
|
||||||
|
valgrind --leak-check=full ./bin/exe
|
||||||
|
|
||||||
|
# Nettoyage : destruction des .o, de l'exécutable et de la documentation
|
||||||
|
clean:
|
||||||
|
rm -rf obj/*.o bin/exe $(DOXYGEN_OUTPUT_DIR)
|
@ -0,0 +1,34 @@
|
|||||||
|
# CC : le compilateur à utiliser
|
||||||
|
CC=clang
|
||||||
|
|
||||||
|
# CFLAGS : les options de compilation
|
||||||
|
CFLAGS=-Wall
|
||||||
|
|
||||||
|
# Les fichiers sources : tous les fichiers présents dans src/
|
||||||
|
SRC=$(wildcard src/*.c)
|
||||||
|
|
||||||
|
# Les fichiers objets (.o)
|
||||||
|
OBJ=$(patsubst src/%.c,obj/%.o,$(SRC))
|
||||||
|
|
||||||
|
# Le répertoire où sera générée la documentation Doxygen
|
||||||
|
DOXYGEN_OUTPUT_DIR=docs
|
||||||
|
|
||||||
|
# Édition des liens : génération de l'exécutable à partir des .o
|
||||||
|
bin/exe: $(OBJ)
|
||||||
|
$(CC) $(OBJ) -o $@
|
||||||
|
|
||||||
|
# Génération des .o à partir des .c correspondants
|
||||||
|
obj/%.o: src/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Génération de la documentation Doxygen
|
||||||
|
doxygen:
|
||||||
|
doxygen Doxyfile
|
||||||
|
|
||||||
|
# Exécution du programme avec Valgrind
|
||||||
|
valgrind: bin/exe
|
||||||
|
valgrind --leak-check=full ./bin/exe
|
||||||
|
|
||||||
|
# Nettoyage : destruction des .o, de l'exécutable et de la documentation
|
||||||
|
clean:
|
||||||
|
rm -rf obj/*.o bin/exe $(DOXYGEN_OUTPUT_DIR)
|
@ -0,0 +1,199 @@
|
|||||||
|
#include "avl.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
Avl creerAvlVide(void) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Booleen estAvlVide(Avl a){
|
||||||
|
if(a == NULL) return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void viderAvl(Avl *pta){
|
||||||
|
if(*pta == NULL) return;
|
||||||
|
viderAvl(&(*pta)->fg);
|
||||||
|
viderAvl(&(*pta)->fd);
|
||||||
|
free(*pta);
|
||||||
|
*pta = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void afficherCroissantAvl(Avl a){
|
||||||
|
if(a == NULL) return;
|
||||||
|
|
||||||
|
afficherCroissantAvl(a->fg);
|
||||||
|
printf("%d ", a->val);
|
||||||
|
afficherCroissantAvl(a->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void afficherDecroissantAvl(Avl a){
|
||||||
|
if(a == NULL) return;
|
||||||
|
|
||||||
|
afficherDecroissantAvl(a->fd);
|
||||||
|
printf("%d ", a->val);
|
||||||
|
afficherDecroissantAvl(a->fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void afficherNtabAvl(int n){
|
||||||
|
for(int i = 0; i<n; i++)
|
||||||
|
printf("\t");
|
||||||
|
}
|
||||||
|
|
||||||
|
void afficherCoucheRecAvl(Avl a, int retrait){
|
||||||
|
if(a->fd != NULL){
|
||||||
|
afficherCoucheRecAvl(a->fd, retrait+1);
|
||||||
|
afficherNtabAvl(retrait); printf(" / \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
afficherNtabAvl(retrait); printf("%d\n", a->val);
|
||||||
|
|
||||||
|
if(a->fg != NULL){
|
||||||
|
afficherNtabAvl(retrait); printf(" \\ \n");
|
||||||
|
afficherCoucheRecAvl(a->fg, retrait+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void afficherCoucheAvl(Avl a){
|
||||||
|
if(a!=NULL) {
|
||||||
|
printf("==================== Affichage ====================\n");
|
||||||
|
afficherCoucheRecAvl(a,0);
|
||||||
|
printf("==================== Fin Affichage ====================\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Booleen rechercherValAvl(Avl a, int val){
|
||||||
|
Booleen rep;
|
||||||
|
if(a == NULL) return FALSE;
|
||||||
|
if(a->val == val) return TRUE;
|
||||||
|
rep = rechercherValAvl(a->fg, val);
|
||||||
|
if(rep == FALSE || !rep)
|
||||||
|
rep = rechercherValAvl(a->fd, val);
|
||||||
|
return rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mettreAjourHauteur(Noeud* ptn) {
|
||||||
|
int hg, hd;
|
||||||
|
|
||||||
|
hg = (ptn->fg==NULL)? -1 : ptn->fd->h;
|
||||||
|
hd = (ptn->fd==NULL)? -1 : ptn->fd->h;
|
||||||
|
|
||||||
|
ptn->h = (hg>hd)? 1+hg : 1+hd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rotationGauche(Avl *pta) {
|
||||||
|
Noeud* racine;
|
||||||
|
racine = (*pta)->fd;
|
||||||
|
(*pta)->fd = racine->fg;
|
||||||
|
racine->fg = *pta;
|
||||||
|
*pta = racine;
|
||||||
|
mettreAjourHauteur((*pta)->fg);
|
||||||
|
mettreAjourHauteur(*pta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rotationDroite(Avl *pta) {
|
||||||
|
Noeud* racine;
|
||||||
|
racine = (*pta)->fg;
|
||||||
|
(*pta)->fg = racine->fd;
|
||||||
|
racine->fd = *pta;
|
||||||
|
*pta = racine;
|
||||||
|
mettreAjourHauteur((*pta)->fd);
|
||||||
|
mettreAjourHauteur(*pta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reequilibrer(Avl* pta) {
|
||||||
|
int hg, hd, hgf, hdf;
|
||||||
|
hg = ((*pta)->fg != NULL)? (*pta)->fg->h : -1;
|
||||||
|
hd = ((*pta)->fd != NULL)? (*pta)->fd->h : -1;
|
||||||
|
if (hg - hd == 2){ // déséquilibre : hg > hd de 2
|
||||||
|
hgf = ((*pta)->fg->fg != NULL)? (*pta)->fg->fg->h : -1;
|
||||||
|
hdf = ((*pta)->fg->fd != NULL)? (*pta)->fg->fd->h : -1;
|
||||||
|
if (hdf > hgf) rotationGauche (& (*pta)->fg);
|
||||||
|
rotationDroite (pta);
|
||||||
|
}
|
||||||
|
else if(hd - hg == 2){ // déséquilibre : hd > hg de 2
|
||||||
|
hgf = ((*pta)->fd->fg != NULL)? (*pta)->fd->fg->h : -1;
|
||||||
|
hdf = ((*pta)->fd->fd != NULL)? (*pta)->fd->fd->h :
|
||||||
|
-1;
|
||||||
|
if (hgf > hdf) rotationDroite (& (*pta)->fd);
|
||||||
|
rotationGauche (pta);
|
||||||
|
}
|
||||||
|
else{ // pas de déséquilibre, on remet juste la hauteur à jour
|
||||||
|
if (hd > hg) (*pta) ->h = hd+1;
|
||||||
|
else (*pta) ->h = hg+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Noeud* creerNoeudAvl(int val){
|
||||||
|
Noeud* tmp = (Noeud*)malloc(sizeof(Noeud));
|
||||||
|
if(tmp == NULL) exit(1);
|
||||||
|
tmp->val = val;
|
||||||
|
tmp->h = 0;
|
||||||
|
tmp->fd = NULL;
|
||||||
|
tmp->fg = NULL;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insererEquilibre(Avl* pta, int val) {
|
||||||
|
if(*pta == NULL)
|
||||||
|
*pta = creerNoeudAvl(val);
|
||||||
|
else {
|
||||||
|
if(val <= (*pta)->val)
|
||||||
|
insererEquilibre(&(*pta)->fg, val);
|
||||||
|
else
|
||||||
|
insererEquilibre(&(*pta)->fd, val);
|
||||||
|
reequilibrer(pta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int oterMaxEquilibre(Avl* pta){
|
||||||
|
Noeud* tmp;
|
||||||
|
int val;
|
||||||
|
if((*pta)->fd == NULL){
|
||||||
|
tmp = *pta;
|
||||||
|
val = tmp->val;
|
||||||
|
*pta = (*pta)->fg;
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
val = oterMaxEquilibre(&(*pta)->fd);
|
||||||
|
reequilibrer(pta);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
Booleen supprimerValEquilibre(Avl *pta, int val){
|
||||||
|
Noeud* tmp;
|
||||||
|
Booleen b;
|
||||||
|
|
||||||
|
if(*pta == NULL) return FALSE;
|
||||||
|
|
||||||
|
if((*pta)->val == val){
|
||||||
|
if((*pta)->fg == NULL){
|
||||||
|
tmp = *pta;
|
||||||
|
*pta = (*pta)->fd; //! si fd est aussi nul, alors *pta sera null !
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
else if((*pta)->fd == NULL){
|
||||||
|
tmp = *pta;
|
||||||
|
*pta = (*pta)->fg;
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
(*pta)->val = oterMaxEquilibre(&(*pta)->fg);
|
||||||
|
reequilibrer(pta);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sinon on continue dans la suite de l'arbre
|
||||||
|
else {
|
||||||
|
if(val < (*pta)->val)
|
||||||
|
b = supprimerValEquilibre(&(*pta)->fg, val);
|
||||||
|
else
|
||||||
|
b = supprimerValEquilibre(&(*pta)->fd, val);
|
||||||
|
if(b) reequilibrer(pta);
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef AVL_H
|
||||||
|
#define AVL_H
|
||||||
|
|
||||||
|
typedef struct noeud {
|
||||||
|
int val;
|
||||||
|
int h;
|
||||||
|
struct noeud *fg, *fd;
|
||||||
|
} Noeud;
|
||||||
|
|
||||||
|
typedef Noeud* Avl;
|
||||||
|
|
||||||
|
typedef enum{FALSE, TRUE} Booleen;
|
||||||
|
|
||||||
|
Avl creerAvlVide(void);
|
||||||
|
Booleen estAvlVide(Avl a);
|
||||||
|
void viderAvl(Avl *pta);
|
||||||
|
|
||||||
|
void afficherCroissantAvl(Avl a);
|
||||||
|
void afficherDecroissantAvl(Avl a);
|
||||||
|
|
||||||
|
void afficherCoucheAvl(Avl a);
|
||||||
|
Booleen rechercherValAvl(Avl a, int val);
|
||||||
|
void insererEquilibre(Avl* pta, int val);
|
||||||
|
Booleen supprimerValEquilibre(Avl* pta, int val);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //AVL_H
|
@ -0,0 +1,82 @@
|
|||||||
|
#include "avl.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
void testAvl(void) {
|
||||||
|
Avl a = creerAvlVide();
|
||||||
|
Avl b = creerAvlVide();
|
||||||
|
Booleen resA, resB, resSupA;
|
||||||
|
if(a == NULL && b == NULL) printf("Arbre créée avec succès.\n");
|
||||||
|
else {
|
||||||
|
printf("Erreur lors de la création de l'arbre !\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
resA = estAvlVide(a);
|
||||||
|
resB = estAvlVide(b);
|
||||||
|
if(resA == TRUE && resB == TRUE) printf("Aucun Pb, les arbres sont bien vides.\n");
|
||||||
|
else printf("Pb, arbres non vide !\n");
|
||||||
|
|
||||||
|
insererEquilibre(&a, 7);
|
||||||
|
insererEquilibre(&a, 9);
|
||||||
|
insererEquilibre(&a, 8);
|
||||||
|
insererEquilibre(&a, 6);
|
||||||
|
|
||||||
|
resA = estAvlVide(a);
|
||||||
|
if(resA == TRUE) printf("Erreur, l'abre incrémenté est vide !\n");
|
||||||
|
else printf("Aucun pb.\n");
|
||||||
|
|
||||||
|
viderAvl(&a);
|
||||||
|
|
||||||
|
resA = estAvlVide(a);
|
||||||
|
if(resA == TRUE) printf("Tout fonctionne, l'arbre A est bien vidé.\n");
|
||||||
|
else printf("Pb, l'arbre a n'a pas été vidé correctement !\n");
|
||||||
|
|
||||||
|
insererEquilibre(&a, 7);
|
||||||
|
insererEquilibre(&a, 9);
|
||||||
|
insererEquilibre(&a, 8);
|
||||||
|
insererEquilibre(&a, 6);
|
||||||
|
insererEquilibre(&a, 1);
|
||||||
|
insererEquilibre(&a, 2);
|
||||||
|
insererEquilibre(&a, 18);
|
||||||
|
insererEquilibre(&a, 11);
|
||||||
|
|
||||||
|
afficherCoucheAvl(a);
|
||||||
|
|
||||||
|
// afficherCroissant(a);
|
||||||
|
// afficherDecroissant(a);
|
||||||
|
|
||||||
|
resSupA = supprimerValEquilibre(&a, 2);
|
||||||
|
if(resSupA == 1) printf("Suppression efféctuée avec succès.");
|
||||||
|
else printf("Pb suppression.");
|
||||||
|
afficherCoucheAvl(a);
|
||||||
|
insererEquilibre(&a, 19);
|
||||||
|
insererEquilibre(&a, 20);
|
||||||
|
insererEquilibre(&a, 21);
|
||||||
|
afficherCoucheAvl(a);
|
||||||
|
afficherCroissantAvl(a);
|
||||||
|
printf("\n");
|
||||||
|
afficherDecroissantAvl(a);
|
||||||
|
printf("\n");
|
||||||
|
// printf("%d", resSupA);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void testTempAvl(void){
|
||||||
|
// int insertion, deb;
|
||||||
|
// deb = time();
|
||||||
|
// Avl a = creerAvlVide();
|
||||||
|
// for(int i = 1; i < 10000; i++) {
|
||||||
|
// insererEquilibre(&a, i);
|
||||||
|
// }
|
||||||
|
// insertion = time() - deb;
|
||||||
|
// printf("%d \n", insertion);
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
testAvl();
|
||||||
|
// testTempAvl();
|
||||||
|
return 0;
|
||||||
|
}
|
After Width: | Height: | Size: 3.9 MiB |
After Width: | Height: | Size: 4.6 MiB |
After Width: | Height: | Size: 3.7 MiB |
After Width: | Height: | Size: 5.0 MiB |
After Width: | Height: | Size: 4.3 MiB |
After Width: | Height: | Size: 5.2 MiB |
After Width: | Height: | Size: 5.2 MiB |
After Width: | Height: | Size: 3.5 MiB |
After Width: | Height: | Size: 4.7 MiB |
After Width: | Height: | Size: 4.3 MiB |
After Width: | Height: | Size: 6.4 MiB |
After Width: | Height: | Size: 5.1 MiB |
After Width: | Height: | Size: 6.9 MiB |
After Width: | Height: | Size: 4.9 MiB |
After Width: | Height: | Size: 5.0 MiB |
After Width: | Height: | Size: 4.4 MiB |
After Width: | Height: | Size: 5.4 MiB |
After Width: | Height: | Size: 3.0 MiB |
After Width: | Height: | Size: 3.4 MiB |
After Width: | Height: | Size: 4.0 MiB |
After Width: | Height: | Size: 3.7 MiB |
After Width: | Height: | Size: 3.3 MiB |
After Width: | Height: | Size: 5.1 MiB |