diff --git a/2A/Algo/tp/C/Correction/1_tp/Makefile b/2A/Algo/tp/C/Correction/1_tp/Makefile new file mode 100644 index 0000000..8299dd3 --- /dev/null +++ b/2A/Algo/tp/C/Correction/1_tp/Makefile @@ -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) diff --git a/2A/Algo/tp/C/Correction/1_tp/src/abr_exo1.c b/2A/Algo/tp/C/Correction/1_tp/src/abr_exo1.c new file mode 100644 index 0000000..825f6b7 --- /dev/null +++ b/2A/Algo/tp/C/Correction/1_tp/src/abr_exo1.c @@ -0,0 +1,148 @@ +#include "abr_exo1.h" + +#include +#include + +ABR creerArbreVide(){ + return NULL; +} + +Booleen estArbreVide(ABR a){ + return (a==NULL)? VRAI:FAUX ; +} + +NoeudABR* creerNoeud(int val){ + NoeudABR* tmp = (NoeudABR*) malloc(sizeof(NoeudABR)); + if(tmp == NULL) exit(1); + tmp->fg = NULL; + tmp->fd = NULL; + tmp->val = val; + return tmp; +} + +void insererEnFeuille(ABR* pta, int val){ + if(*pta == NULL){ + *pta = creerNoeud(val); + } + else if (val <= (*pta)->val){ + insererEnFeuille(&(*pta)->fg, val); + } + else{ + insererEnFeuille(&(*pta)->fd, val); + } +} + +void viderArbre(ABR* pta){ + if(*pta != NULL){ + viderArbre(&(*pta)->fg); + viderArbre(&(*pta)->fd); + free(*pta); + *pta = NULL; + } +} + +void afficherCroissant(ABR a){ + if (a!= NULL){ + afficherCroissant(a->fg); + printf("%d, ", a->val); + afficherCroissant(a->fd); + } +} + +void afficherDecroissant(ABR a){ + if(a!=NULL){ + afficherDecroissant(a->fd); + printf("%d, ", a->val); + afficherDecroissant(a->fg); + } +} + +// pour l'affichage couché : + +void afficherNtab(int n){for(int i = 0; ifd !=NULL){ + afficherCoucheRec(a->fd, retrait+1); + afficherNtab(retrait); printf(" / \n"); + } + + afficherNtab(retrait); printf("%d\n", a->val); + + if(a->fg !=NULL){ + afficherNtab(retrait); printf(" \\ \n"); + afficherCoucheRec(a->fg,retrait+1); + } +} + + +void afficherCouche(ABR a){ + if(a!=NULL) + afficherCoucheRec(a,0); +} + + + +Booleen rechercherVal(ABR a, int val){ + if(a==NULL) return FAUX; + if(a->val == val) return VRAI; + if(val < a->val) return rechercherVal(a->fg,val); + else return rechercherVal(a->fd,val); +} + +//-------------------------------------------------------- + +// pour la suppression + +// supprime le noeud contenant la valeur max de l'arbre +// et retourne sa valeur. +// ATTENTION : *pta doit être un arbre non vide +int oterMax(ABR * pta){ + NoeudABR * tmp; + int val; + if((*pta)->fd==NULL){ + tmp = *pta; + val = tmp->val; + *pta = (*pta)->fg; + free(tmp); + } + else{ + val = oterMax(&(*pta)->fd); + } + return val; +} + +Booleen supprimerVal(ABR *pta, int val){ + NoeudABR* tmp; + Booleen b; + + if(*pta==NULL) return FAUX; + + // si la valeur est à la racine de l'arbre + if ((*pta)->val == val){ + if((*pta)->fg == NULL){ + tmp = *pta; + *pta = (*pta)->fd; + free(tmp); //////////////// et non pas free(*A); + } + else if((*pta)->fd == NULL ){ + tmp = *pta; + *pta = (*pta)->fg; + free(tmp); //////////////// et non pas free(*A); + } + else /// cad si ((*pta)->fd != NULL && (*pta)->fg != NULL) + (*pta)->val = oterMax(&(*pta)->fg); + + return VRAI; + } + + // sinon on continue dans la suite de l'arbre ( à gauche ou à droite) + else if (val < (*pta)->val){ + b = supprimerVal(&(*pta)->fg, val); + } + else{ + b = supprimerVal(&(*pta)->fd, val); + } + + return b; +} \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/1_tp/src/abr_exo1.h b/2A/Algo/tp/C/Correction/1_tp/src/abr_exo1.h new file mode 100644 index 0000000..114c796 --- /dev/null +++ b/2A/Algo/tp/C/Correction/1_tp/src/abr_exo1.h @@ -0,0 +1,94 @@ +/** + \file abr_exo1.h + \author C. SIMON + \date 02/07/2022 + \brief package des ABR : structure et fonctionnalités de base + */ + + +#ifndef ABR_EXO1_H +#define ABR_EXO1_H + + +#include "pratique.h" + +/** + \brief structure de noeud pour un ABR + */ + + +typedef struct noeudABR{ + int val; /**< valeur contenue dans le noeud */ + struct noeudABR* fg; /**< adresse du sous-arbre gauche */ + struct noeudABR* fd; /**< adresse du sous-arbre droit */ +}NoeudABR; + +/** + \brief définition d'un ABR + */ +typedef NoeudABR* ABR; + + +/** + \brief crée un arbre vide + \return l'arbre vide créé +*/ +ABR creerArbreVide(); + +/** + \brief indique si l'arbre a est vide + \return VRAI si l'arbre est vide, FAUX sinon +*/ +Booleen estArbreVide(ABR a); + +/** + \brief insère en feuille + \param pta l'adresse de l'ABR à modifier + \param val la valeur à insérer dans l'ABR +*/ +void insererEnFeuille(ABR* pta, int val); + +/** + \brief vide l'ABR en libérant la mémoire + \param pta l'adresse de l'ABR à modifier +*/ +void viderArbre(ABR* pta); + +/** + \brief affiche les valeurs de l'ABR en liste croissante + \param a l'ABR dont on souhaite afficher les valeurs +*/ +void afficherCroissant(ABR a); + + +/** + \brief affiche les valeurs de l'ABR en liste décroissante + \param a l'ABR dont on souhaite afficher les valeurs +*/ +void afficherDecroissant(ABR a); + +/** + \brief affiche l'ABR dessiné couché + \param a l'ABR à afficher +*/ +void afficherCouche(ABR a); + + +/** + \brief recherche et indique si la valeur passée en paramètre + est dans l'ABR ou pas + \param a l'ABR dans lequel on souhaite effectuer la recherche + \param val la valeur cherchée + \return VRAI si la valeur est dans l'ABR, FAUX sinon +*/ +Booleen rechercherVal(ABR a, int val); + +/** + \brief supprime la première occurrence de la valeur dans l'arbre + si la valeur y est, ou ne fait rien si elle n'y est pas + \param pta l'adresse de l'ABR à modifier + \param val la valeur à supprimer dans l'ABR +*/ +Booleen supprimerVal(ABR *pta, int val); + +#endif // ABR_EXO1_H \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/1_tp/src/avl_exo2.c b/2A/Algo/tp/C/Correction/1_tp/src/avl_exo2.c new file mode 100644 index 0000000..dc507d1 --- /dev/null +++ b/2A/Algo/tp/C/Correction/1_tp/src/avl_exo2.c @@ -0,0 +1,220 @@ +#include "avl_exo2.h" +#include +#include + +AVL creerArbreVide(){ + return NULL; +} + +Booleen estArbreVide(AVL a){ + return (a==NULL)? VRAI:FAUX ; +} + + +void viderArbre(AVL* pta){ + if(*pta != NULL){ + viderArbre(&(*pta)->fg); + viderArbre(&(*pta)->fd); + free(*pta); + *pta = NULL; + } +} + +void afficherCroissant(AVL a){ + if (a!= NULL){ + afficherCroissant(a->fg); + printf("%d, ", a->val); + afficherCroissant(a->fd); + } +} + +void afficherDecroissant(AVL a){ + if(a!=NULL){ + afficherDecroissant(a->fd); + printf("%d, ", a->val); + afficherDecroissant(a->fg); + } +} + +// pour l'affichage couché : + +void afficherNtab(int n){for(int i = 0; ifd !=NULL){ + afficherCoucheRec(a->fd, retrait+1); + afficherNtab(retrait); printf(" / \n"); + } + + afficherNtab(retrait); printf("%d (%d)\n", a->val, a->h); + + if(a->fg !=NULL){ + afficherNtab(retrait); printf(" \\ \n"); + afficherCoucheRec(a->fg,retrait+1); + } +} + + +void afficherCouche(AVL a){ + if(a!=NULL) + afficherCoucheRec(a,0); +} + + + +Booleen rechercherVal(AVL a, int val){ + if(a==NULL) return FAUX; + if(a->val == val) return VRAI; + if(val < a->val) return rechercherVal(a->fg,val); + else return rechercherVal(a->fd,val); +} + + + +// précondition : a n'est pas vide +void mettreAjourHauteur(AVL a){ + int hg, hd; + if(a->fg==NULL) hg = -1; + else hg = a->fg->h; + + if(a->fd==NULL) hd = -1; + else hd = a->fd->h; + + if(hg>hd) a->h = 1+hg; + else a->h = 1+hd; +} + +// ------------ pour les rotations + +void rotationGauche(AVL* pta){ + NoeudAVL* racine = (*pta)->fd; + (*pta)->fd = racine->fg; + mettreAjourHauteur(*pta); + racine->fg = *pta; + mettreAjourHauteur(racine); + *pta = racine; +} + +void rotationDroite(AVL* pta){ + NoeudAVL* racine = (*pta)->fg; + (*pta)->fg = racine->fd; + mettreAjourHauteur(*pta); + racine->fd = *pta; + mettreAjourHauteur(racine); + *pta = racine; +} + +NoeudAVL* creerNoeud(int val){ + NoeudAVL* tmp = (NoeudAVL*) malloc(sizeof(NoeudAVL)); + if(tmp == NULL) exit(1); + tmp->fg = NULL; + tmp->fd = NULL; + tmp->val = val; + tmp->h = 0; + return tmp; +} + +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; + } +} + +// version insertion qui conserve l'équilibre de l'AVL +void insererEquilibre(AVL* pta, int val){ + if(*pta == NULL){ + *pta = creerNoeud(val); + } + else{ + if (val <= (*pta)->val){ + insererEquilibre(&(*pta)->fg, val); + } + else{ + insererEquilibre(&(*pta)->fd, val); + } + reequilibrer(pta); + } +} + + + + +// pour la suppression + +// supprime le noeud contenant la valeur max de l'arbre +// et retourne sa valeur. +// ATTENTION : *pta doit être un arbre non vide +int oterMax(AVL * pta){ + NoeudAVL * tmp; + int val; + if((*pta)->fd==NULL){ + tmp = *pta; + val = tmp->val; + *pta = (*pta)->fg; + free(tmp); + } + else{ + val = oterMax(&(*pta)->fd); + reequilibrer(pta); + } + return val; +} + +Booleen supprimerVal(AVL *pta, int val){ + NoeudAVL* tmp; + Booleen b; + + if(*pta==NULL) return FAUX; + + // si la valeur est à la racine de l'arbre + if ((*pta)->val == val){ + if((*pta)->fg == NULL){ + tmp = *pta; + *pta = (*pta)->fd; + free(tmp); + // rien à faire pour la hauteur + // et pas de ré-èquilibration à faire ici + } + else if((*pta)->fd == NULL ){ + tmp = *pta; + *pta = (*pta)->fg; + free(tmp); + // rien à faire pour la hauteur + // et pas de ré-èquilibration à faire + } + else{ /// cad si ((*pta)->fd != NULL && (*pta)->fg != NULL) + (*pta)->val = oterMax(&(*pta)->fg); + reequilibrer(pta); + } + return VRAI; + } + + // sinon on continue dans la suite de l'arbre ( à gauche ou à droite) + else{ + if (val < (*pta)->val){ + b = supprimerVal(&(*pta)->fg, val); + } + else{ + b = supprimerVal(&(*pta)->fd, val); + } + if(b) reequilibrer(pta); + } + + return b; +} diff --git a/2A/Algo/tp/C/Correction/1_tp/src/avl_exo2.h b/2A/Algo/tp/C/Correction/1_tp/src/avl_exo2.h new file mode 100644 index 0000000..fc9596c --- /dev/null +++ b/2A/Algo/tp/C/Correction/1_tp/src/avl_exo2.h @@ -0,0 +1,98 @@ +/** + \file avl_exo2.h + \author C. SIMON + \date 02/07/2022 + \brief package des AVL : structure et fonctionnalités de base + */ + +#ifndef AVL_EXO2_H +#define AVL_EXO2_H + +#include "pratique.h" + + + + +/** + \brief structure de noeud pour un AVL + */ +typedef struct noeudAVL{ + int val; /**< valeur contenue dans le noeud */ + struct noeudAVL* fg; /**< adresse du sous-arbre gauche */ + struct noeudAVL* fd; /**< adresse du sous-arbre droit */ + int h; /**< hauteur du noeud : = 0 si pas de fils, + sinon = 1+ max ( h du ss-arbre gauche, h du ss-arbre droit) + */ +}NoeudAVL; + +/** + \brief définition d'un AVL + */ +typedef NoeudAVL* AVL; + + +/** + \brief crée un arbre vide + \return l'arbre vide créé +*/ +AVL creerArbreVide(); + +/** + \brief indique si l'arbre a est vide + \return VRAI si l'arbre est vide, FAUX sinon +*/ +Booleen estArbreVide(AVL a); + +/** + \brief insère en feuille + \param pta l'adresse de l'AVL à modifier + \param val la valeur à insérer dans l'AVL +*/ +void insererEquilibre(AVL* pta, int val); + +/** + \brief vide l'AVL en libérant la mémoire + \param pta l'adresse de l'AVL à modifier +*/ +void viderArbre(AVL* pta); + + +/** + \brief affiche les valeurs de l'AVL en liste croissante + \param a l'AVL dont on souhaite afficher les valeurs +*/ +void afficherCroissant(AVL a); + +/** + \brief affiche les valeurs de l'AVL en liste décroissante + \param a l'AVL dont on souhaite afficher les valeurs +*/ +void afficherDecroissant(AVL a); + + +/** + \brief affiche l'AVL dessiné couché + \param a l'AVL à afficher +*/ +void afficherCouche(AVL a); + + +/** + \brief recherche et indique si la valeur passée en paramètre + est dans l'AVL ou pas + \param a l'AVL dans lequel on souhaite effectuer la recherche + \param val la valeur cherchée + \return VRAI si la valeur est dans l'AVL, FAUX sinon +*/ +Booleen rechercherVal(AVL a, int val); + + +/** + \brief supprime la première occurrence de la valeur dans l'arbre + si la valeur y est, ou ne fait rien si elle n'y est pas + \param pta l'adresse de l'AVL à modifier + \param val la valeur à supprimer dans l'AVL +*/ +Booleen supprimerVal(AVL *pta, int val); + +#endif // AVL_EXO2_H \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/1_tp/src/pratique.h b/2A/Algo/tp/C/Correction/1_tp/src/pratique.h new file mode 100644 index 0000000..60d83b7 --- /dev/null +++ b/2A/Algo/tp/C/Correction/1_tp/src/pratique.h @@ -0,0 +1,12 @@ +/** + \file pratique.h + \author C. SIMON + \date 02/07/2022 + \brief fichier contenant des types ou fonctionnalités utiles +*/ +#ifndef PRATIQUE +#define PRATIQUE + +typedef enum {FAUX, VRAI}Booleen; + +#endif // PRATIQUE \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/1_tp/src/testABR.c b/2A/Algo/tp/C/Correction/1_tp/src/testABR.c new file mode 100644 index 0000000..595724a --- /dev/null +++ b/2A/Algo/tp/C/Correction/1_tp/src/testABR.c @@ -0,0 +1,117 @@ +#include "abr_exo1.h" // les ABR +#include +#include + + +void testExo1(){ + Booleen b; + ABR a = creerArbreVide(); + + if(estArbreVide(a)) printf("OK : l'arbre est vide à sa création\n"); + else printf("ERREUR : l'arbre devrait être vide à sa création\n"); + + insererEnFeuille(&a, 10); + if(! estArbreVide(a)) + printf("OK : l'arbre n'est pas vide après une insertion\n"); + else + printf("ERREUR : l'arbre devrait ne pas être vide après une insertion\n"); + + insererEnFeuille(&a, 5); + insererEnFeuille(&a, 15); + insererEnFeuille(&a, 7); + insererEnFeuille(&a, 20); + + printf("après insertion de 10,5,15,7 et 20\n"); + + afficherCouche(a); + + insererEnFeuille(&a, 6); + insererEnFeuille(&a, 3); + insererEnFeuille(&a, 8); + insererEnFeuille(&a, 2); + insererEnFeuille(&a, 4); + insererEnFeuille(&a, 17); + + printf("après insertion de 6,3,8,2,4 et 17\n"); + afficherCouche(a); + + afficherCroissant(a); printf("\n"); + afficherDecroissant(a);printf("\n"); + + b = rechercherVal(a, 7); + if(b) printf("OK : 7 trouvé\n"); + else printf("ERREUR : 7 pas trouvé\n"); + + b = rechercherVal(a, 16); + if(b) printf("ERREUR : 16 trouvé\n"); + else printf("OK : 16 pas trouvé\n"); + + printf(" suppression de 10\n"); + b=supprimerVal(&a,10); + + if(b) printf("OK : 10 a été supprimé\n"); + else printf("ERREUR : 10 n'a pas pu être supprimé\n"); + + afficherCouche(a); + + viderArbre(&a); + + if(estArbreVide(a)) printf("OK : l'arbre a bien été vidé\n"); + else printf("ERREUR : l'arbre n'a pas été vidé visiblement\n"); + +} + +void mesureTemps(int nb){ + Booleen b; + ABR a = creerArbreVide(); + clock_t t; + double temps; + + printf("TEST pour ABR déséquilibré de %d noeuds : \n", nb); + + t = clock(); + for(int i = 1; i<=nb ; i++) + insererEnFeuille(&a, i); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("\t temps de la construction : %f s\n", temps); + + t = clock(); + b = rechercherVal(a, -1); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("\t temps pour la recherche de -1 : %f s\n", temps); + + t = clock(); + b = rechercherVal(a, nb/2); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("\t temps pour la recherche de %d : %f s\n", nb/2, temps); + + t = clock(); + b = rechercherVal(a, nb+1); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("\t temps pour la recherche de %d : %f s\n", nb+1, temps); + + t = clock(); + viderArbre(&a); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("\t temps pour vider l'arbre : %f s\n\n", temps); +} + + +void testExo3(){ + mesureTemps(10000); + mesureTemps(50000); + mesureTemps(100000); + +} + +int main(void){ + // testExo1(); + testExo3(); + + return 0; +} \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/1_tp/src/testAVL.c b/2A/Algo/tp/C/Correction/1_tp/src/testAVL.c new file mode 100644 index 0000000..28d7cdf --- /dev/null +++ b/2A/Algo/tp/C/Correction/1_tp/src/testAVL.c @@ -0,0 +1,102 @@ +#include "avl_exo2.h" // les AVL +#include +#include + +void testExo2(){ + Booleen b; + AVL a = creerArbreVide(); + + if(estArbreVide(a)) printf("OK : l'arbre est vide à sa création\n"); + else printf("ERREUR : l'arbre devrait être vide à sa création\n"); + + insererEquilibre(&a, 10); + if(! estArbreVide(a)) + printf("OK : l'arbre n'est pas vide après une insertion\n"); + else + printf("ERREUR : l'arbre devrait ne pas être vide après une insertion\n"); + + afficherCouche(a); + insererEquilibre(&a, 5); + afficherCouche(a); + insererEquilibre(&a, 15); + afficherCouche(a); + insererEquilibre(&a, 12); + afficherCouche(a); + insererEquilibre(&a, 7); + afficherCouche(a); + insererEquilibre(&a, 8); + afficherCouche(a); + insererEquilibre(&a, 9); + + printf("après insertion de 10,5,15,12,7,8 et 9\n"); + + afficherCouche(a); + + printf(" suppression de 5\n"); + b=supprimerVal(&a,5); + + if(b) printf("OK : 5 a été supprimé\n"); + else printf("ERREUR : 5 n'a pas pu être supprimé\n"); + + afficherCouche(a); + + viderArbre(&a); + + if(estArbreVide(a)) printf("OK : l'arbre a bien été vidé\n"); + else printf("ERREUR : l'arbre n'a pas été vidé visiblement\n"); + +} + +void mesureTemps(int nb){ + Booleen b; + AVL a = creerArbreVide(); + clock_t t; + double temps; + + printf("TEST pour AVL de %d noeuds : \n", nb); + + t = clock(); + for(int i = 1; i<=nb ; i++) + insererEquilibre(&a, i); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("temps de la construction : %f s\n", temps); + + t = clock(); + b=rechercherVal(a, -1); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("temps pour la recherche de -1 : %f s\n", temps); + + t = clock(); + b = rechercherVal(a, nb/2); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("\t temps pour la recherche de %d : %f s\n", nb/2, temps); + + t = clock(); + b = rechercherVal(a, nb+1); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("\t temps pour la recherche de %d : %f s\n", nb+1, temps); + + t = clock(); + viderArbre(&a); + t = clock() - t; + temps = ((double)t)/CLOCKS_PER_SEC; // in seconds + printf("\t temps pour vider l'arbre : %f s\n\n", temps); +} + +void testExo3(){ + mesureTemps(10000); + mesureTemps(50000); + mesureTemps(100000); +} + + +int main(void){ + //testExo2(); + testExo3(); + + return 0; +} \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/1_tp/sujet_TP_arbre_bin.pdf b/2A/Algo/tp/C/Correction/1_tp/sujet_TP_arbre_bin.pdf new file mode 100644 index 0000000..a4926c5 Binary files /dev/null and b/2A/Algo/tp/C/Correction/1_tp/sujet_TP_arbre_bin.pdf differ diff --git a/2A/Algo/tp/C/Correction/2_tp/Makefile b/2A/Algo/tp/C/Correction/2_tp/Makefile new file mode 100644 index 0000000..8299dd3 --- /dev/null +++ b/2A/Algo/tp/C/Correction/2_tp/Makefile @@ -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) diff --git a/2A/Algo/tp/C/Correction/2_tp/bin/exe b/2A/Algo/tp/C/Correction/2_tp/bin/exe new file mode 100755 index 0000000..07c73aa Binary files /dev/null and b/2A/Algo/tp/C/Correction/2_tp/bin/exe differ diff --git a/2A/Algo/tp/C/Correction/2_tp/src/codeRetour.c b/2A/Algo/tp/C/Correction/2_tp/src/codeRetour.c new file mode 100644 index 0000000..c204c16 --- /dev/null +++ b/2A/Algo/tp/C/Correction/2_tp/src/codeRetour.c @@ -0,0 +1,49 @@ +#include "codeRetour.h" +#include + +void afficheMessageCodeRetour(CodeRetour code){ + switch(code){ + case NON : + printf("non "); + break; + case OUI: + printf("oui "); + break; + case OK : + printf("ok, opération effectuée "); + break; + case PB_MEMOIRE: + printf("problème mémoire "); + break; + case PB_NOEUD_DEJA_EXISTANT: + printf("problème : noeud déjà existant "); + break; + case PB_NOEUD_DEP_NON_EXISTANT: + printf("problème : noeud de départ non existant "); + break; + case PB_NOEUD_ARR_NON_EXISTANT: + printf("problème : noeud d'arrivée non existant "); + break; + case PB_NOEUD_NON_EXISTANT: + printf("problème : noeud non existant "); + break; + case PB_ARC_DEJA_EXISTANT: + printf("problème : arc déjà existant "); + break; + case PB_ARC_NON_EXISTANT: + printf("problème : arc non existant "); + break; + case PB_OUVERTURE_FICHIER: + printf("problème ouverture du fichier "); + break; + case PB_RESEAU_ERRONNE: + printf("problème : réseau erroné "); + break; + default : + printf("ERREUR : code retour inconnu\n"); + } + printf("\n"); + + + +} \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/2_tp/src/codeRetour.h b/2A/Algo/tp/C/Correction/2_tp/src/codeRetour.h new file mode 100644 index 0000000..e64da81 --- /dev/null +++ b/2A/Algo/tp/C/Correction/2_tp/src/codeRetour.h @@ -0,0 +1,41 @@ +/** + \file codeRetour.h + \author C. SIMON + \date 03/07/2022 + \brief gestion des codes de retour qui peuvent être retournés par les + primitives de gestion des réseaux + */ + + +#ifndef CODERETOUR_H +#define CODERETOUR_H + + +/** + * énumération de constantes pour gérer différents retour de fonctions + * concernant les réseaux + */ +typedef enum{ + NON, + OUI, + OK, + PB_MEMOIRE, + PB_NOEUD_DEJA_EXISTANT, + PB_NOEUD_DEP_NON_EXISTANT, + PB_NOEUD_ARR_NON_EXISTANT, + PB_NOEUD_NON_EXISTANT, + PB_ARC_DEJA_EXISTANT, + PB_ARC_NON_EXISTANT, + PB_OUVERTURE_FICHIER, + PB_RESEAU_ERRONNE +} CodeRetour; + + +/** + \brief gère l'affichage de chaque code de retour par un message + explicite à l'écran + \param code le code à afficher + */ +void afficheMessageCodeRetour(CodeRetour code); + +#endif // CODERETOUR_H \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/2_tp/src/reseau.c b/2A/Algo/tp/C/Correction/2_tp/src/reseau.c new file mode 100644 index 0000000..b95155b --- /dev/null +++ b/2A/Algo/tp/C/Correction/2_tp/src/reseau.c @@ -0,0 +1,500 @@ +#include +#include + +#include"reseau.h" + + + + +/************************ question 1 ************************/ +Reseau initialiser(){ + return NULL; +} + +CodeRetour estVide(Reseau r){ + if (r==NULL) return OUI; + else return NON; +} + +/************************ question 2 ************************/ +/* affichage du graphe représentant le réseau */ +void affiche(Reseau r){ + Noeud *tmp = r; + Arc *a; + while (tmp != NULL){ + printf(" %d : \n ",tmp->num); + a = tmp->listeArc; + while(a != NULL){ + printf("\t -> %d \n ",a->extremite->num); + a = a->suivant; + } + tmp = tmp->suiv; + } +} + + +/************************ question 3 ************************/ +/* retourne un pointeur sur le noeud cherché ou NULL sinon */ +Noeud * rechercheNoeud(Reseau r, int num){ + Noeud* tmp; + + tmp = r; + while(tmp != NULL){ + if(tmp->num == num) return tmp; + tmp = tmp->suiv; + } + return tmp; +} + +/************************ question 4 ************************/ +/* + retourne OK si l'ajout a été fait + PB_NOEUD_DEJA_EXISTANT si le noeud existe déjà (ajout non fait) + PB_MEMOIRE si problème allocation mémoire +*/ +CodeRetour ajoutNoeud(Reseau *pr, int num){ + Noeud * tmp; + + tmp = rechercheNoeud(*pr, num); + if (tmp != NULL) return PB_NOEUD_DEJA_EXISTANT; + + + tmp=(Noeud*)malloc(sizeof(Noeud)); + if(tmp==NULL) return PB_MEMOIRE; + tmp->num = num; + tmp->listeArc = NULL; + tmp->marque = 0; + tmp->suiv = *pr; + *pr = tmp; + return OK; +} + +/************************ question 5 ************************/ +/* + précondition : dep et arr pointent sur deux noeuds réels du réseau + retourne + NON si l'arc n'existe pas + OUI s'il existe + */ +CodeRetour existenceArcPt(Noeud* dep, Noeud *arr){ + Arc* tmp; + + tmp = dep->listeArc; + while(tmp != NULL){ + if(tmp->extremite == arr) return OUI; + tmp = tmp->suivant; + } + return NON; +} + + +/************************/ +/* retourne + PB_NOEUD_DEP_NON_EXISTANT si le noeud de départ n'existe pas + PB_NOEUD_ARR_NON_EXISTANT si le noeud d'arrivée n'existe pas + NON si l'arc n'existe pas + OUI s'il existe +*/ +CodeRetour existenceConnexion(Reseau r, int dep, int arr){ + Noeud *pa, *pb; + + pa = rechercheNoeud(r, dep); + if(pa == NULL) return PB_NOEUD_DEP_NON_EXISTANT; + pb = rechercheNoeud(r, arr); + if(pb == NULL) return PB_NOEUD_ARR_NON_EXISTANT; + + return existenceArcPt(pa, pb); +} + +/************************ question 6 ************************/ +/* retourne OK si l'arc allant de dep à arr a bien été ajouté + PB_NOEUD_DEP_NON_EXISTANT si dep n'existe pas + PB_NOEUD_ARR_NON_EXISTANT si arr n'existe pas + PB_ARC_DEJA_EXISTANT si l'arc existe déjà + PB_MEMOIRE si problème allocation mémoire + */ +CodeRetour ajoutArc(Reseau r, int dep, int arr){ + Noeud *pa, *pb; + Arc * tmp; + + pa = rechercheNoeud(r, dep); + if(pa == NULL) return PB_NOEUD_DEP_NON_EXISTANT; + pb = rechercheNoeud(r, arr); + if(pb == NULL) return PB_NOEUD_ARR_NON_EXISTANT; + + if(existenceArcPt(pa,pb) == OUI) return PB_ARC_DEJA_EXISTANT; + + /* sinon on ajoute cet arc */ + tmp=(Arc*)malloc(sizeof(Arc)); + if(tmp == NULL) return PB_MEMOIRE; + tmp->extremite = pb; + tmp->suivant = pa->listeArc; + pa->listeArc = tmp; + return OK; +} + +/************************ question 7 ************************/ +/* précondition dep et arr pointent sur deux noeuds existants du réseau + retourne OK si la destruction a été effectuée + PB_ARC_NON_EXISTANT si l'arc n'existait pas +*/ +CodeRetour destructionArcPt(Noeud* dep, Noeud* arr){ + Arc * tmp, *tmpav; + + if(existenceArcPt(dep,arr) == NON) return PB_ARC_NON_EXISTANT; + + /* sinon on le détruit */ + tmp = dep->listeArc; + + /*si c'est le premier */ + if(tmp->extremite == arr) + dep->listeArc = tmp->suivant; + else{ + while(tmp->extremite != arr){ + tmpav = tmp; + tmp = tmp->suivant; + } + tmpav->suivant = tmp->suivant; + } + tmp->extremite = NULL; + free(tmp); + return OK; +} +/************************/ +/* retourne OK si destruction effectuée + PB_NOEUD_DEP_NON_EXISTANT si dep n'existe pas + PB_NOEUD_ARR_NON_EXISTANT si arr n'existe pas + PB_ARC_NON_EXISTANT si l'arc n'existe pas +*/ +CodeRetour destructionArc(Reseau r, int dep, int arr){ + Noeud *pa, *pb; + + pa = rechercheNoeud(r, dep); + if(pa == NULL) return PB_NOEUD_DEP_NON_EXISTANT; + pb = rechercheNoeud(r, arr); + if(pb == NULL) return PB_NOEUD_ARR_NON_EXISTANT; + + return destructionArcPt(pa, pb); +} + +/************************ question 8 ************************/ +/* lorsque l'on détruit un noeud il faut également détruire + tous les arcs qui partent de lui et tous les arcs qui pointent + sur lui. + retourne OK si destruction effectuée + PB_NOEUD_NON_EXISTANT si num n'existe pas */ +CodeRetour destructionNoeud(Reseau *pr, int num){ + Noeud *ptn, *pt2; + Arc * tmpa; + + /* on cherche le noeud */ + ptn=rechercheNoeud(*pr, num); + + if(ptn == NULL) return PB_NOEUD_NON_EXISTANT; + + /* on enlève tous les arcs partant de lui */ + while(ptn->listeArc != NULL){ + tmpa = ptn->listeArc; + ptn->listeArc = tmpa->suivant; + free(tmpa); + } + + /* on enlève tous les arcs pointant sur lui */ + pt2 = *pr; + while(pt2 != NULL){ + destructionArcPt(pt2, ptn); + pt2 = pt2->suiv; + } + + /* on détruit le noeud en refaisant d'abord le chainage */ + if(ptn == *pr) + *pr = (*pr)->suiv; + else{ + // on place pt2 sur le noeud juste avant ptn + pt2 = *pr; + while(pt2->suiv !=ptn) + pt2 = pt2->suiv; + pt2->suiv = ptn->suiv; + } + free(ptn); + return OK; +} + + + +/************************ question en plus ************************/ +void destructionReseau(Reseau *pr){ + while(*pr != NULL) + destructionNoeud(pr,(*pr)->num); +} + +/************************ question 9 ************************/ +int compteNoeud(Reseau r){ + Noeud * pt; + int cpt; + + pt = r; + cpt = 0; + while(pt != NULL){ + pt = pt->suiv; + cpt++; + } + + return cpt; +} +/************************ question 10 ************************/ +int compteArc(Reseau r){ + Noeud * pt; + Arc *tmp; + int cpt; + + pt = r; + cpt = 0; + while(pt != NULL){ + tmp = pt->listeArc; + while(tmp != NULL){ + tmp = tmp->suivant; + cpt++; + } + pt = pt->suiv; + } + + return cpt; +} + + + + +/*----------------------------------------------------*/ + +/************************ question 11 - a) ************************/ +/* fonction qui détermine si une machine donnée peut communiquer avec une autre également donnée + utilise un parcours en profondeur + retourne PB_NOEUD_DEP_NON_EXISTANT + PB_NOEUD_ARR_NON_EXISTANT + OUI si dep peut communiquer avec arr + NON si dep ne peut pas communiquer avec arr (dep et arr existent) +*/ + +/* mise à zéro de la marque de chaque noeud */ +void toutMarquerAZero(Reseau r){ + Noeud * tmp = r; + while(tmp != NULL){ + tmp->marque = 0; + tmp = tmp->suiv; + } +} + +CodeRetour visitePourPeutCommuniquer(Noeud * pdep, Noeud * parr){ + Arc* tmpa; + + pdep->marque = 1; + if(pdep == parr) return OUI; + + tmpa = pdep->listeArc; + while(tmpa !=NULL){ + if(tmpa->extremite->marque == 0) + if(visitePourPeutCommuniquer(tmpa->extremite, parr)==OUI) + return OUI; + tmpa = tmpa->suivant; + } + return NON; +} + +CodeRetour peutCommuniquer(Reseau r, int dep, int arr){ + Noeud *pdep, *parr; + + pdep = rechercheNoeud(r, dep); + if(pdep == NULL) return PB_NOEUD_DEP_NON_EXISTANT; + parr = rechercheNoeud(r, arr); + if(parr == NULL) return PB_NOEUD_ARR_NON_EXISTANT; + + toutMarquerAZero(r); + + return visitePourPeutCommuniquer(pdep, parr); +} + + + + +/************************ question 11 - b) ************************/ +/* fonction qui détermine et affiche l'ensemble des noeuds avec + lesquels un noeud donné peut communiquer + utilise un parcours en profondeur + retourne PB_NOEUD_DEP_NON_EXISTANT si le neoud de départ n'existe pas + OK si l'affichage a pu se faire +*/ + +void visiterPourMarquerQuiPeutCommuniquer(Noeud * pdep){ + Arc* tmpa; + + pdep->marque = 1; + + tmpa = pdep->listeArc; + while(tmpa !=NULL){ + if(tmpa->extremite->marque == 0) + visiterPourMarquerQuiPeutCommuniquer(tmpa->extremite); + tmpa = tmpa->suivant; + } + +} + +void afficheAvecQuiCommuniquer(Reseau r, int dep){ + Noeud *pdep, *tmp; + + pdep = rechercheNoeud(r, dep); + if(pdep == NULL){ + printf("problème : %d n'existe pas \n", dep); + return; + } + + toutMarquerAZero(r); + + visiterPourMarquerQuiPeutCommuniquer(pdep); + + // puis on affiche tous les noeuds qui sont à 1 + printf("les noeuds avec lesquels %d peut communiquer sont : \n", dep); + tmp = r; + while(tmp!= NULL){ + if(tmp->marque == 1) + printf("\t %d \n", tmp->num); + tmp = tmp->suiv; + } +} + + + +/***************** Etape 3 : question 1 ************************/ +/* fonction de chargement du réseau en mémoire + en cas de problème le réseau reste vide + retourne OK si chargement effectué + PB_OUVERTURE_FICHIER si pb ouverture fichier + PB_RESEAU_ERRONNE si reseau erroné : + noeud déjà existant, + connexion entre deux noeuds non existants (un au moins), + ou si connexion déjà existante + PB_MEMOIRE si problème allocation mémoire +*/ +CodeRetour chargement(char * nomFichier, Reseau * pr){ + FILE * fp; + int n,m,i,a,b, num; + char code; + + *pr = NULL; + fp = fopen(nomFichier,"rt"); + if(fp == NULL) + return PB_OUVERTURE_FICHIER; + + /* lecture du nombre de noeuds */ + fscanf(fp,"%d",&n); + + /* lecture du nombre de connexions */ + fscanf(fp,"%d",&m); + + /* lecture des noeuds */ + for(i=0;inum); + ptn = ptn->suiv; + } + fprintf(fp, "\n"); + + ptn = r; + while(ptn != NULL){ + pta = ptn->listeArc; + while(pta != NULL){ + fprintf(fp, "%d %d\n", ptn->num, pta->extremite->num); + pta= pta->suivant; + } + ptn = ptn->suiv; + } + + fclose(fp); + return OK; +} + +/******************* Etape 3 : question 2 ************************/ +/* fonction qui exporte le réseau dans un fichier dot pour pouvoir + être lu par dotty + retourne OK si sauvegarde effectuée + PB_OUVERTURE_FICHIER si pb ouverture fichier +*/ +CodeRetour exporte(char * nomFichier, Reseau r){ + FILE *fp; + Noeud *tmp; + Arc *tmpa; + char c = '"'; + + fp = fopen(nomFichier,"wt"); + if(fp == NULL) return PB_OUVERTURE_FICHIER; + + fprintf(fp,"digraph family\n"); + fprintf(fp,"{\n"); + + /* sauvegarde des sommets */ + tmp = r; + while(tmp != NULL){ + fprintf(fp,"%d [label= %cNoeud %d%c]\n",tmp->num,c,tmp->num,c); + tmp = tmp->suiv; + } + + /* sauvegarde des connexions */ + tmp = r; + while(tmp != NULL){ + tmpa = tmp->listeArc; + while(tmpa != NULL){ + fprintf(fp,"%d->%d \n",tmp->num, tmpa->extremite->num); + tmpa = tmpa->suivant; + } + tmp = tmp->suiv; + } + fprintf(fp,"}\n"); + + fclose(fp); + return OK; +} diff --git a/2A/Algo/tp/C/Correction/2_tp/src/reseau.h b/2A/Algo/tp/C/Correction/2_tp/src/reseau.h new file mode 100644 index 0000000..455c43c --- /dev/null +++ b/2A/Algo/tp/C/Correction/2_tp/src/reseau.h @@ -0,0 +1,240 @@ +/** + \file reseau.h + \author C. SIMON + \date 03/07/2022 + \brief un réseau informatique : la structure de donnée et ses primitives de + gestion. + Un réseau est une liste chaînée de noeuds. Chaque noeud représente un + ordinateur et connait la liste des orditeurs avec lesquells il est + connecté. + */ + + +#include "codeRetour.h" + +#ifndef RESEAU_H +#define RESEAU_H + +/** + \brief structure de noeud. Un noeud représentera un ordinateur du + réseau. +*/ +typedef struct CellNoeud{ + int num; /**< numero identifiant l'ordinateur */ + int marque; /**< marque permettant de savoir si le noeud a déjà été + parcouru pendant le parcours en profondeur par exemple */ + struct CellNoeud *suiv; /**< adresse du noeud suivant dans la liste des noeuds*/ + struct CellArc *listeArc; /**< une liste d'arcs représentant la liste des + ordinateurs avec lesquels il est connecté*/ +}Noeud; + +/** + \brief la structure d'arc permet de représenter une connection vers un + ordinateur. Pour que les arcs puissent être chainés les uns aux autres, + chaque arc connait un suivant dans une telle liste. + */ +typedef struct CellArc{ + struct CellNoeud *extremite; /**< extrémité de l'arc*/ + struct CellArc *suivant; /**< arc suivant dans la liste d'arcs */ +}Arc; + +/** + \brief structure de réseau : un réseau est une liste des noeuds qui le composent. +*/ +typedef Noeud * Reseau; + + + + +/*------------------------------------------------------*/ +/* primitives de gestion de réseau : */ +/*------------------------------------------------------*/ + +/** + \brief crée et initialise du réseau à vide +*/ +Reseau initialiser(); + +/** + \brief vérifie si le réseau est vide + \param r le réseau + \return OUI si il est vide, NON sinon + */ +CodeRetour estVide(Reseau r); + +/** + \brief affiche le réseau. + \param r le réseau à afficher +*/ +void affiche(Reseau r); + +/** + \brief recherche dans le réseau le noeud correspondant au numero donné. + \param r le réseau + \param num le numéro que l'on cherche + \return l'adresse du noeud si trouvé ou NULL sinon +*/ +Noeud * rechercheNoeud(Reseau r, int num); + + +/** + \brief ajoute un noeud donné par son numéro dans le réseau donné + \param pr adresse du réseau à modifier + \param num numéro du noeud à ajouter + \return un code indiquant si l'opération a été faite ou pas + (et pour quelle raison): + - OK si l'ajout a été fait + - PB_NOEUD_DEJA_EXISTANT si le noeud existe déjà (ajout non fait) + - PB_MEMOIRE si problème allocation mémoire +*/ +CodeRetour ajoutNoeud(Reseau *pr, int num); + + +/** + \brief Fonction indiquant si une connexion/un arc entre les deux noeuds + donnés par leur numéro existe ou non. + \param r le réseau + \param dep le numéro du noeud de départ de l'arc + \param arr le numéro du noeud d'arrivée de l'arc + \return un code : + PB_NOEUD_DEP_NON_EXISTANT si le noeud de départ n'existe pas + PB_NOEUD_ARR_NON_EXISTANT si le noeud d'arrivée n'existe pas + NON si l'arc n'existe pas (les neouds extrémité existant) + OUI s'il existe +*/ +CodeRetour existenceConnexion(Reseau r, int dep, int arr); + + +/** + \brief ajoute un arc donné par ses extrémités dans le réseau. + En cas de problème l'arc n'est pas ajouté. + \param r le réseau + \param dep le numéro du noeud de départ de l'arc + \param arr le numéro du noeud d'arrivée de l'arc + \return un code : + OK si l'arc allant de dep à arr a bien été ajouté + PB_NOEUD_DEP_NON_EXISTANT si dep n'existe pas + PB_NOEUD_ARR_NON_EXISTANT si arr n'existe pas + PB_ARC_DEJA_EXISTANT si l'arc existe déjà + PB_MEMOIRE si problème allocation mémoire + */ +CodeRetour ajoutArc(Reseau r, int dep, int arr); + + + +/** + \brief détruit un arc donné par les numéros de ses extrémités. + \param r le réseau + \param dep le numéro du noeud de départ de l'arc à supprimer + \param arr le numéro du noeud d'arrivée de l'arc à supprimer + \return un code : + OK si destruction effectuée + PB_NOEUD_DEP_NON_EXISTANT si dep n'existe pas + PB_NOEUD_ARR_NON_EXISTANT si arr n'existe pas + PB_ARC_NON_EXISTANT si l'arc n'existe pas +*/ +CodeRetour destructionArc(Reseau r, int dep, int arr); + + + +/** + \brief détruit un noeud(donné par son numéro) + dans un réseau donné. La destruction du noeud implique la + destruction des connections entrantes et sortantes de ce noeud + \param pr l'adresse du réseau à modifier + \param num le numéro du noeud à supprimer + \return un code : + OK si destruction effectuée + PB_NOEUD_NON_EXISTANT si numéro ne désigne pas un noeud du réseau +*/ +CodeRetour destructionNoeud(Reseau *pr, int num); + + + +/** + \brief compte le nombre de noeuds d'un réseau. + \param r le réseau + \return le nombre de noeuds composant le réseau +*/ +int compteNoeud(Reseau r); + +/** + \brief compte et le nombre de connexions/d'arcs d'un réseau donné. + \param r le réseau + \return le nombre d'arcs composant le réseau +*/ +int compteArc(Reseau r); + + +/*Fonction qui détruit le réseau passé en paramètre. */ +void destructionReseau(Reseau *pr); + + + +/** + \brief détermine si une machine/noeud donnée peut communiquer avec + une autre également donnée. + \param r le réseau + \param dep le numéro de la machine de départ de la communication + \param arr le numéro de la machine d'arrivée de la communication + \return un code : + PB_NOEUD_DEP_NON_EXISTANT + PB_NOEUD_ARR_NON_EXISTANT + OUI si dep peut communiquer avec arr + NON si dep ne peut pas communiquer avec arr (dep et arr existent) +*/ +CodeRetour peutCommuniquer(Reseau r, int dep, int arr); + +/** + \brief détermine et affiche l'ensemble des noeuds avec + lesquels un noeud donné peut communiquer + \param r le réseau + \param dep le numéro du noeud donné +*/ +void afficheAvecQuiCommuniquer(Reseau r, int dep); + + +// du plus : seulement si il reste du temps (ne tombera pas en exam + +/*------------------------------------------------------*/ +/* primitives de sauvegarde et de chargement */ +/*------------------------------------------------------*/ +/** + \brief charge le réseau en mémoire. + En cas de problème le réseau reste vide. + \param nomFichier le nom du fichier texte contenant le réseau + \param pr l'adresse du réseau qui est chargé + \return un code + OK si chargement effectué + PB_OUVERTURE_FICHIER si pb d'ouverture de fichier + PB_RESEAU_ERRONNE si reseau erroné : + noeud déjà existant, + connexion entre deux noeuds non existants (un au moins), + ou si connexion déjà existante + PB_MEMOIRE si problème allocation mémoire +*/ +CodeRetour chargement(char * nomFichier, Reseau * pr); + + +/** + \brief sauvegarde le réseau dans un fichier texte. + \param nomFichier le nom du fichier texte + \param r le réseau à sauvegarder + \return un code + OK si sauvegarde effectuée + PB_OUVERTURE_FICHIER si pb ouverture fichier +*/ +CodeRetour sauvegarde(char * nomFichier, Reseau r); + + +/** + \brief exporte le réseau dans un fichier dot + \param nomFichier le nom du fichier texte de format dot + \param r le réseau à exporter + \return un code + OK si export effectué + PB_OUVERTURE_FICHIER si pb ouverture fichier +*/ +CodeRetour exporte(char * nomFichier, Reseau r); + +#endif // RESEAU_H \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/2_tp/src/testReseau.c b/2A/Algo/tp/C/Correction/2_tp/src/testReseau.c new file mode 100644 index 0000000..a19924f --- /dev/null +++ b/2A/Algo/tp/C/Correction/2_tp/src/testReseau.c @@ -0,0 +1,167 @@ +#include +#include + +#include "reseau.h" +#include "codeRetour.h" + +int menu(){ + int choix; + printf("--------------------------------\n"); + printf("que desirez vous ?\n"); + printf(" 0- quitter\n"); + printf(" 1- ajouter un noeud \n"); + printf(" 2- ajouter une connexion\n"); + printf(" 3- rechercher un noeud\n"); + printf(" 4- rechercher une connexion \n"); + printf(" 5- detruire un noeud\n"); + printf(" 6- detruire une connexion \n"); + printf(" 7- detruire tout le reseau \n"); + printf(" 8- connaitre le nombre de noeuds \n"); + printf(" 9- connaitre le nombre de connexions \n"); + printf(" 10- charger un reseau \n"); + printf(" 11- sauvegarder un reseau \n"); + printf(" 12- exporter un reseau \n"); + printf(" 13- afficher le reseau (affichage de base) \n"); + printf(" 14- savoir si une machine peut communiquer avec une autre\n"); + printf(" 15- connaitre toutes les machines avec lesquelles peut communiquer une machine donnée\n"); + printf("--------------------------------\n"); + scanf("%d", &choix); + return choix; +} + + +int main(void){ + Reseau r; + int choix, num, num2; + CodeRetour code; + Noeud * ptn; + + char nomFichier[30]; + + choix = 12; + r = initialiser(); + + while(choix != 0){ + choix = menu(); + + switch(choix){ + case 0 : printf("au revoir \n"); + break; + case 1: + printf("donner le numero du noeud a ajouter : "); + scanf("%d", &num); + code = ajoutNoeud(&r, num); + printf("ajout du noeud %d dans le réseau : \n\t", num); + afficheMessageCodeRetour(code); printf("\n"); + break; + + case 2: + printf("donner les deux extremites de la connexion a ajouter \n"); + printf("(2 numeros separes par un espace) : "); + scanf("%d %d", &num, &num2); + code = ajoutArc(r, num, num2); + printf("ajout de l'arc %d -> %d : \n\t", num, num2); + afficheMessageCodeRetour(code); printf("\n"); + break; + + case 3: + printf("donner le numero du noeud à rechercher : "); + scanf("%d", &num); + ptn=rechercheNoeud(r,num); + if(ptn != NULL) printf("noeud trouve \n"); + else printf("noeud non trouve \n"); + break; + + case 4: + printf("donner les deux extremites de la connexion à rechercher \n"); + printf("(2 numeros séparés par un espace) : "); + scanf("%d %d", &num, &num2); + code = existenceConnexion(r, num, num2); + printf("l'arc %d ->%d existe-t-il? ", num, num2); + afficheMessageCodeRetour(code); printf("\n"); + break; + + case 5: + printf("donner le numero du noeud à détruire : "); + scanf("%d", &num); + code = destructionNoeud(&r,num); + printf("destruction du noeud %d : ",num); + afficheMessageCodeRetour(code); printf("\n"); + break; + + case 6: + printf("donner les deux extremites de la connexion a detruire \n"); + printf("(2 numeros separes par un espace) : "); + scanf("%d %d", &num, &num2); + code = destructionArc(r, num, num2); + printf("destruction de la connexion %d->%d : ",num, num2); + afficheMessageCodeRetour(code); printf("\n"); + break; + + case 7: + destructionReseau(&r); + break; + + case 8: + num = compteNoeud(r); + printf("le reseau comporte %d noeuds \n",num); + break; + + case 9: + num = compteArc(r); + printf("le reseau comporte %d arcs \n",num); + break; + + case 10: //charger + printf("quel est le nom du fichier contenant le reseau? "); + scanf("%s",nomFichier); + destructionReseau(&r); /// destruction du réseau déjà existant + code = chargement(nomFichier, &r); + printf("chargement du réseau à partir de %s : ",nomFichier); + afficheMessageCodeRetour(code); printf("\n"); + break; + + case 11: //sauvegarder + printf("dans quel fichier voulez vous sauver le reseau? "); + scanf("%s",nomFichier); + code= sauvegarde(nomFichier,r); + printf("sauvegarde dans %s : ", nomFichier); + afficheMessageCodeRetour(code); printf("\n"); + break; + + case 12: //exporter + printf("dans quel fichier voulez vous exporter le reseau? "); + scanf("%s",nomFichier); + code= exporte(nomFichier,r); + printf("export dans %s : ", nomFichier); + afficheMessageCodeRetour(code); printf("\n"); + break; + + case 13 : + affiche(r); + break; + + case 14: + printf("numéro de la première machine : "); + scanf("%d", &num); + printf("numéro de la deuxième machine : "); + scanf("%d", &num2); + + code = peutCommuniquer(r,num,num2); + printf("est-ce que %d peut communiquer avec %d : ", num,num2); + afficheMessageCodeRetour(code); printf("\n"); + break; + + case 15: + printf("numéro de la machine : "); + scanf("%d", &num); + afficheAvecQuiCommuniquer(r,num); + break; + + default : printf("erreur de frappe ! \n"); + break; + + } + } + return 0; +} \ No newline at end of file diff --git a/2A/Algo/tp/C/Correction/2_tp/sujet_TP_graphes.pdf b/2A/Algo/tp/C/Correction/2_tp/sujet_TP_graphes.pdf new file mode 100644 index 0000000..95412a5 Binary files /dev/null and b/2A/Algo/tp/C/Correction/2_tp/sujet_TP_graphes.pdf differ diff --git a/2A/Anglais/CV.docx b/2A/Anglais/CV.docx new file mode 100644 index 0000000..93dbf1c Binary files /dev/null and b/2A/Anglais/CV.docx differ diff --git a/2A/Anglais/IMG_5264.HEIC b/2A/Anglais/IMG_5264.HEIC new file mode 100644 index 0000000..52bbff3 Binary files /dev/null and b/2A/Anglais/IMG_5264.HEIC differ diff --git a/2A/Anglais/IMG_5265.HEIC b/2A/Anglais/IMG_5265.HEIC new file mode 100644 index 0000000..55808f2 Binary files /dev/null and b/2A/Anglais/IMG_5265.HEIC differ diff --git a/2A/Anglais/IMG_5266.HEIC b/2A/Anglais/IMG_5266.HEIC new file mode 100644 index 0000000..61d4fe8 Binary files /dev/null and b/2A/Anglais/IMG_5266.HEIC differ diff --git a/2A/Anglais/IMG_5267.HEIC b/2A/Anglais/IMG_5267.HEIC new file mode 100644 index 0000000..ed8a34b Binary files /dev/null and b/2A/Anglais/IMG_5267.HEIC differ diff --git a/2A/Anglais/IMG_5268.HEIC b/2A/Anglais/IMG_5268.HEIC new file mode 100644 index 0000000..90d8265 Binary files /dev/null and b/2A/Anglais/IMG_5268.HEIC differ diff --git a/2A/Anglais/IMG_5269.HEIC b/2A/Anglais/IMG_5269.HEIC new file mode 100644 index 0000000..c766109 Binary files /dev/null and b/2A/Anglais/IMG_5269.HEIC differ diff --git a/2A/Anglais/IMG_5270.HEIC b/2A/Anglais/IMG_5270.HEIC new file mode 100644 index 0000000..260786d Binary files /dev/null and b/2A/Anglais/IMG_5270.HEIC differ diff --git a/2A/Anglais/IMG_5271.HEIC b/2A/Anglais/IMG_5271.HEIC new file mode 100644 index 0000000..2c285f6 Binary files /dev/null and b/2A/Anglais/IMG_5271.HEIC differ diff --git a/2A/systeme/tp/1_tp/Course 1.pdf b/2A/systeme/tp/1_tp/Course 1.pdf new file mode 100644 index 0000000..09943a2 Binary files /dev/null and b/2A/systeme/tp/1_tp/Course 1.pdf differ diff --git a/2A/Algo/tp/C/2_tp/bin/exe b/2A/systeme/tp/1_tp/ex1 similarity index 85% rename from 2A/Algo/tp/C/2_tp/bin/exe rename to 2A/systeme/tp/1_tp/ex1 index afd6579..aa4e379 100755 Binary files a/2A/Algo/tp/C/2_tp/bin/exe and b/2A/systeme/tp/1_tp/ex1 differ diff --git a/2A/systeme/tp/1_tp/ex1.c b/2A/systeme/tp/1_tp/ex1.c new file mode 100644 index 0000000..4f19bb0 --- /dev/null +++ b/2A/systeme/tp/1_tp/ex1.c @@ -0,0 +1,13 @@ +#include +#include + +int main(int argc, char* argv[]) +{ + for(int i = 0; i < argc; ++i) + printf("argument %d : %s \n", i, argv[i]); + puts("\n----------------\n"); //mieux qu'un printf car moins gourmand pour char() + + printf("PATH => %s\n", getenv("PATH")); + + return 0; +} diff --git a/2A/systeme/tp/1_tp/ex2 b/2A/systeme/tp/1_tp/ex2 new file mode 100755 index 0000000..dd8788c Binary files /dev/null and b/2A/systeme/tp/1_tp/ex2 differ diff --git a/2A/systeme/tp/1_tp/ex2.c b/2A/systeme/tp/1_tp/ex2.c new file mode 100644 index 0000000..1c31060 --- /dev/null +++ b/2A/systeme/tp/1_tp/ex2.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +int main(void) { + + if(system("ps -f") == -1) { + perror("pb appel systeme"); + exit(errno); + } + if(execlp("/bin/ps", "ps", "-f", NULL) == -1) { + perror("ZUT, pb avec le exec"); + exit(errno); + } + + printf("Terminé !\n"); + + exit(0); +} diff --git a/2A/systeme/tp/1_tp/ex3 b/2A/systeme/tp/1_tp/ex3 new file mode 100755 index 0000000..c173fcc Binary files /dev/null and b/2A/systeme/tp/1_tp/ex3 differ diff --git a/2A/systeme/tp/1_tp/ex3.c b/2A/systeme/tp/1_tp/ex3.c new file mode 100644 index 0000000..70aacf6 --- /dev/null +++ b/2A/systeme/tp/1_tp/ex3.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + + pid_t pid; + int i, etat; + struct timespec t; + + switch(pid=fork()) { + + case -1 : /* Oups !!! fork n'a pas marché !*/ + perror("fork"); exit(errno); + + case 0 : /* Code du fils */ + printf("[fils]: je suis le fils de pid %d\n", getpid()); + for (i=0; i<10 ; i++) { + printf("[fils]: %d\n",i); + t.tv_sec=0; + t.tv_nsec=500000000; + nanosleep(&t,NULL); + } + system("ps -f"); + exit(2); + break; + + default : /* Code du père*/ + if ((pid=wait(&etat))==-1) { + perror("pb avec le wait"); + exit(errno); + } + if (WIFEXITED(etat)) + printf("[pere]: mon fils %d a retourne le code %d\n", pid, WEXITSTATUS(etat)); + else + printf("[pere]: mon fils %d s est mal termine\n",pid); + + printf("[pere]: Fin du processus pere de pid %d.\n", getpid()); + } + + + + exit(0); +} diff --git a/2A/systeme/tp/1_tp/ex4.c b/2A/systeme/tp/1_tp/ex4.c new file mode 100644 index 0000000..f4d7487 --- /dev/null +++ b/2A/systeme/tp/1_tp/ex4.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include + + +int main(int argc, char **argv) { + + pid_t pid; + int time = 2; + status = 0; + + switch(pid=fork()) { + + case -1 : // Oups !!! fork n'a pas marché ! + perror("fork"); exit(errno); + + case 0 : // Code du fils + printf("je suis le fils de %d\n", getppid()); + for(int i = 0; i <= 9; ++i) { + printf("%d \n", i); //\n ==> signale pour dire qu'il faut afficher à l'écran + usleep(500000); + } + system("ps -f"); + exit(2); + + default : // Code du père + pid = wait(&status); + printf("Mon fils m'a renvoyé le code de retour %d\n", WEXITSTATUS(status); + printf("Fin du processus père de pid %d.\n", getpid()); + } + + + + exit(0); +}