Graphes/TP/TP1.md
2024-02-28 12:00:20 +01:00

3.2 KiB

TP Graphes 1 : Codage de graphes


Exercice 1 : Matrice d'adjacence

Un graphe sera représenté ici par une structure contenant un entier (son ordre), un entier booléen (orienté ou non), et son ensemble d'arêtes, représenté par sa matrice d'adjacence :

struct graphe{
  int ordre; // l'ordre du graphe
  int** adj; // la matrice d'adjacence, donnée par un double tableau dynamique
  int oriente; // vaut 0 si le graphe est non orienté, 1 sinon
};

typedef struct graphe graphe;

Question : Ecrire une fonction permettant de créer un graphe vide à partir de son ordre et de son orientation :

graphe creergraphe(int ord,int or);

La fonction devra entre autres réserver de la mémoire pour la matrice d'adjacence.

Question : Ecrire une fonction prenant un graphe et deux sommets, et ajoutant une arête entre ces deux sommets :

void ajoutArete(graphe g,int v,int w){

Question : Si le graphe est non orienté, toute arête de v vers w ajoute également une arête de w vers v. Modifiez la fonction précédente pour en prendre compte.

Question : Créez dans le main le graphe des frontières de la France (on ne considérera pas les micro-états).


Exercice 2 : Voisinage

Question : Ecrire une fonction permettant de d'afficher les voisins d'un sommet dans un graphe non orienté. Testez votre fonction sur le graphe créé au premier exercice.

Question : Modifiez votre fonction pour afficher les voisins sortants et les voisins entrants si le graphe est orienté.

Question : Ecrire une fonction comptant le nombre de voisins d'un sommet dans un graphe, en gérant les cas orienté ou non orienté.

Question : Vérifiez sur le graphe créé la propriété du cours :

La somme du nombre de voisins de tous les états est égal au nombre d'arêtes x 2.


Exercice 3 : Listes

Il est possible de coder l'ensemble des voisins d'un sommet par une liste chaînée. Pour cela, on utilise un codage des listes chaînées :

struct mail{
  int valeur;
  struct mail *suivant;
};

Ainsi que des fonctions les utilisant :

int tailleM(maillon *m){  //Renvoie la taille d'une liste
  int res=0;
  while(m!=NULL)){
    res++;
    m=m->suivant;
  }
  return res;
}

void affiche(maillon *m){  //Affiche le contenu d'une liste
  if(m==NULL){
    printf("\n");
  }else{
    printf("%d, ",m->valeur);
    affiche(m->suivant);
  }
}


maillon* ajouterDebut(maillon* m,int val){ //Renvoie la liste enrichie de val
  maillon* res=malloc(sizeof(maillon));
  res->valeur=val;
  res->suivant=m;
  return res;
}

int estDans(maillon* m,int val){ //Renvoie 0 si val n'est pas dans la liste, 1 sinon
  if(m==NULL){
    return 0;
  }
  if(m->valeur==val){
    return 1;
  }
  return estDans(m->suivant,val);
}

A partir de ces listes, on peut donc définir un graphe comme suit :

struct graphe{
  int ordre;
  maillon** voisins;
  int oriente;
};

Où voisins est un tableau de listes chaînées.

Question : Recréez les fonctions codées dans les exercices précédents en les adaptant à cet encodage de graphes. Normalement, vous devriez pouvoir utiliser la même fonction main pour tester votre code.