parent
356c63b7aa
commit
c27ba2958c
@ -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,148 @@
|
|||||||
|
#include "abr_exo1.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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; i<n; i++) printf("\t"); }
|
||||||
|
|
||||||
|
void afficherCoucheRec(ABR a, int retrait){
|
||||||
|
if(a->fd !=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;
|
||||||
|
}
|
@ -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
|
@ -0,0 +1,220 @@
|
|||||||
|
#include "avl_exo2.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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; i<n; i++) printf("\t"); }
|
||||||
|
|
||||||
|
void afficherCoucheRec(AVL a, int retrait){
|
||||||
|
if(a->fd !=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;
|
||||||
|
}
|
@ -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
|
@ -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
|
@ -0,0 +1,117 @@
|
|||||||
|
#include "abr_exo1.h" // les ABR
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
#include "avl_exo2.h" // les AVL
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Binary file not shown.
@ -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)
|
Binary file not shown.
@ -0,0 +1,49 @@
|
|||||||
|
#include "codeRetour.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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
|
@ -0,0 +1,500 @@
|
|||||||
|
#include<stdlib.h>
|
||||||
|
#include<stdio.h>
|
||||||
|
|
||||||
|
#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;i<n;i++){
|
||||||
|
fscanf(fp,"%d",&num);
|
||||||
|
code = ajoutNoeud(pr,num);
|
||||||
|
if(code == PB_NOEUD_DEJA_EXISTANT ) return PB_RESEAU_ERRONNE;
|
||||||
|
else if (code == PB_MEMOIRE) return PB_MEMOIRE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lecture des connexions */
|
||||||
|
for(i=0;i<m;i++){
|
||||||
|
fscanf(fp,"%d",&a);
|
||||||
|
fscanf(fp,"%d",&b);
|
||||||
|
|
||||||
|
code = ajoutArc(*pr,a,b);
|
||||||
|
if(code != OK){
|
||||||
|
destructionReseau(pr);
|
||||||
|
fclose(fp);
|
||||||
|
if(code == PB_MEMOIRE) return PB_MEMOIRE;
|
||||||
|
else return PB_RESEAU_ERRONNE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------*/
|
||||||
|
/* fonction de sauvegarde du réseau en mémoire */
|
||||||
|
/* retourne OK si sauvegarde ok
|
||||||
|
PB_OUVERTURE_FICHIER si pb ouverture fichier
|
||||||
|
*/
|
||||||
|
CodeRetour sauvegarde(char * nomFichier, Reseau r){
|
||||||
|
int nb;
|
||||||
|
FILE *fp;
|
||||||
|
Noeud *ptn;
|
||||||
|
Arc *pta;
|
||||||
|
|
||||||
|
fp = fopen(nomFichier,"wt");
|
||||||
|
if(fp == NULL) return PB_OUVERTURE_FICHIER;
|
||||||
|
|
||||||
|
nb = compteNoeud(r);
|
||||||
|
fprintf(fp,"%d\n", nb);
|
||||||
|
|
||||||
|
nb = compteArc(r);
|
||||||
|
fprintf(fp,"%d\n", nb);
|
||||||
|
|
||||||
|
ptn = r;
|
||||||
|
while(ptn != NULL){
|
||||||
|
fprintf(fp, "%d ",ptn->num);
|
||||||
|
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;
|
||||||
|
}
|
@ -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
|
@ -0,0 +1,167 @@
|
|||||||
|
#include<stdlib.h>
|
||||||
|
#include<stdio.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,13 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Binary file not shown.
@ -0,0 +1,20 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
Binary file not shown.
@ -0,0 +1,48 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
Loading…
Reference in new issue