TD3 Liste Piles Files Correction Informatique3 PREING2 S1
Télécharger le TD3 Liste Piles Files Correction en pdf
Exercice 1
- On reprend le code du TD1 et on l’adapte pour la liste doublement chaînée de chaine de char
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_C 20 // Définit la taille maximale d'une chaîne de caractères à 20
typedef struct chainon_struct {
char value[MAX_C]; // Le contenu du chainon, ici une chaîne de caractères
struct chainon_struct* previous; // Pointeur vers l'élément précédent dans la liste
struct chainon_struct* next; // Pointeur vers l'élément suivant dans la liste
} Chainon;
typedef struct liste_struct {
Chainon* tete; // Pointeur vers le premier élément de la liste
Chainon* fin; // Pointeur vers le dernier élément de la liste
} Liste;
Chainon* creationChainon(char* str) {
// Vérification si la chaîne d'entrée est nulle
if (str == NULL) {
exit(EXIT_FAILURE); // Si oui, on quitte le programme
}
// Vérification que la chaîne ne dépasse pas la taille maximale
if (strlen(str) > MAX_C) {
exit(EXIT_FAILURE); // Si oui, on quitte le programme
}
Chainon* nouveau = malloc(sizeof(Chainon));
if (nouveau == NULL) {
exit(EXIT_FAILURE); // Si l'allocation échoue, on quitte le programme
}
// Copier la chaîne de caractères dans le nouveau chainon
strcpy(nouveau->value, str);
nouveau->previous = NULL; // Le pointeur vers le chainon précédent est initialisé à NULL
nouveau->next = NULL; // Le pointeur vers le chainon suivant est initialisé à NULL
return nouveau; // Retourne le nouveau chainon créé
}
Liste creationListe() {
Liste lst;
lst.tete = NULL; // Initialise la tête de la liste à NULL (liste vide)
lst.fin = NULL; // Initialise la fin de la liste à NULL (liste vide)
return lst; // Retourne la liste vide créée
}
- On crée la fonction pour comparer deux chaînes de caractères (mot1 et mot2) la fonction retourne 1 si mot1 est avant mot2 dans l’ordre alphabétique, sinon 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int compareMot(char *mot1, char* mot2) {
// Vérification que les chaînes ne sont pas nulles
if (mot1 == NULL || mot2 == NULL) {
exit(EXIT_FAILURE); // Si oui, on quitte le programme
}
// Vérification que les chaînes ne dépassent pas la taille maximale autorisée
if (strlen(mot1) > MAX_C-1 || strlen(mot2) > MAX_C-1) {
exit(EXIT_FAILURE); // Si oui, on quitte le programme
}
// Comparaison des chaînes de caractères
if (strcmp(mot1, mot2) < 0) {
return 1; // mot1 est avant mot2 dans l'ordre alphabétique
} else {
return 0; // mot1 n'est pas avant mot2
}
}
- On crée la fonction qui insère un chainon au début de la liste
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Chainon* insertDebut(Chainon* pliste, char* a) {
// Vérification que la chaîne n'est pas nulle et ne dépasse pas la taille maximale
if (a == NULL || strlen(a) > MAX_C) {
exit(EXIT_FAILURE); // Si oui, on quitte le programme
}
// Si la liste est vide, on crée le premier chainon
if (pliste == NULL) {
pliste = creationChainon(a);
} else {
// Sinon, on crée un nouveau chainon et on le place en tête
Chainon* nouveau = creationChainon(a);
nouveau->next = pliste; // Le nouveau chainon pointe vers l'ancien premier chainon
nouveau->previous = NULL; // Le nouveau chainon n'a pas de précédent
pliste = nouveau; // On met à jour la tête de la liste
}
return pliste; // Retourne la nouvelle tête de la liste
}
- On crée la fonction pour insérer un mot dans la liste de manière triée
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void insertListe(char* mot1, Liste* pliste) {
// Vérification que la chaîne n'est pas nulle et que la liste n'est pas nulle
if (mot1 == NULL || pliste == NULL || strlen(mot1) >= MAX_C) {
exit(EXIT_FAILURE); // Si oui, on quitte le programme
}
// Si la liste est vide, on insère le premier chainon
if (pliste->tete == NULL) {
pliste->tete = creationChainon(mot1);
pliste->fin = pliste->tete; // La tête et la fin sont identiques car il n'y a qu'un élément
return;
}
// Si le mot doit être inséré au début de la liste
if (compareMot(mot1, pliste->tete->value)) {
pliste->tete = insertDebut(pliste->tete, mot1); // On insère le mot en tête
return;
}
// Recherche de la bonne position dans la liste pour insérer le mot
Chainon* borne1 = pliste->tete; // borne1 commence à la tête de la liste
Chainon* borne2 = pliste->tete->next; // borne2 pointe sur l'élément suivant
while (borne2 != NULL) {
// Si mot1 doit être inséré entre borne1 et borne2
if (compareMot(borne1->value, mot1) && compareMot(mot1, borne2->value)) {
Chainon* new = creationChainon(mot1); // Crée un nouveau chainon
new->previous = borne1; // Mise à jour des liens
new->next = borne2;
borne1->next = new;
borne2->previous = new;
return;
}
// Avance dans la liste
borne1 = borne2;
borne2 = borne2->next;
}
// Si le mot doit être inséré à la fin de la liste
pliste->fin->next = creationChainon(mot1); // Insère le nouveau chainon après l'actuelle fin
pliste->fin->next->previous = pliste->fin; // Met à jour les liens
pliste->fin = pliste->fin->next; // Le nouveau chainon devient la nouvelle fin de la liste
}
- On crée la fonction pour afficher la liste dans l’ordre croissant (de la tête à la fin)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void affiche(Liste *pliste) {
if (pliste == NULL) {
exit(EXIT_FAILURE); // Si la liste est nulle, on quitte le programme
}
// Si la liste est vide, on affiche des crochets vides
if (pliste->tete == NULL) {
printf("[]\n");
return;
}
Chainon* actual = pliste->tete; // Commence à la tête de la liste
printf("[");
// Parcourt chaque chainon de la liste
while (actual->next != NULL) {
printf("%s, ",actual->value); // Affiche la valeur du chainon courant
actual = actual->next; // Passe au chainon suivant
}
// Affiche le dernier élément sans virgule
printf("%s]\n",actual->value);
}
- On crée la fonction pour afficher la liste dans l’ordre inverse (de la fin à la tête)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void afficheInv(Liste *pliste) {
if (pliste == NULL) {
exit(EXIT_FAILURE); // Si la liste est nulle, on quitte le programme
}
// Si la liste est vide, on affiche des crochets vides
if (pliste->tete == NULL) {
printf("[]\n");
return;
}
Chainon* actual = pliste->fin; // Commence à la fin de la liste
printf("[");
// Parcourt chaque chainon de la liste à l'envers
while (actual->previous != NULL) {
printf("%s, ",actual->value); // Affiche la valeur du chainon courant
actual = actual->previous; // Passe au chainon précédent
}
// Affiche le dernier élément sans virgule
printf("%s]\n",actual->value);
}
- On teste dans le main l’insertion de mots et leur affichage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main() {
Liste l = creationListe(); // Crée une liste vide
// Insertion de 20 mots dans la liste
insertListe("popito", &l);
insertListe("chat", &l);
insertListe("chainon", &l);
insertListe("article", &l);
insertListe("zoo", &l);
insertListe("tete", &l);
insertListe("valeur", &l);
insertListe("inspiration", &l);
insertListe("insertion", &l);
insertListe("vinland", &l);
insertListe("interpole", &l);
insertListe("microphone", &l);
insertListe("raciste", &l);
insertListe("rattrapage", &l);
insertListe("file", &l);
insertListe("pile", &l);
insertListe("kebab", &l);
insertListe("flemme", &l);
insertListe("procrastination", &l);
insertListe("affichage", &l);
// Affichage de la liste dans l'ordre croissant
affiche(&l);
// Affichage de la liste dans l'ordre décroissant
afficheInv(&l);
return 0; // Fin du programme
}
Exercice 2
- On définition de la structure Crepe pour représenter une crêpe avec son diamètre
1
2
3
4
5
6
7
typedef struct crepe_struct {
int diametre;
struct crepe_struct* next;
} Crepe;
typedef Crepe* Pcrepe;
- On crée la fonction pour insérer une crêpe dans une file
1
2
3
4
5
6
7
8
9
10
11
12
Pcrepe inserFile(Pcrepe tete, Crepe* crepe) {
if (tete == NULL) {
return crepe; // Si la file est vide, la crêpe devient la tête
}
Pcrepe temp = tete;
while (temp->next != NULL) {
temp = temp->next; // Parcours jusqu'à la fin de la file
}
temp->next = crepe;
return tete;
}
- On crée la fonction pour supprimer une crêpe dans une FILE
1
2
3
4
5
6
7
8
9
Pcrepe suppFile(Pcrepe tete) {
if (tete == NULL) {
return NULL; // Si la file est vide
}
Pcrepe temp = tete->next;
free(tete); // Libération de la mémoire
return temp; // Le suivant devient la nouvelle tête
}
- On crée la fonction pour insérer une crêpe dans une PILE
1
2
3
4
5
Pcrepe inserPile(Pcrepe tete, Crepe* crepe) {
crepe->next = tete; // La nouvelle crêpe pointe sur l'ancienne tête
return crepe; // La nouvelle crêpe devient la tête
}
- On crée la fonction pour supprimer une crêpe dans une PILE
1
2
3
4
Pcrepe suppPile(Pcrepe tete) {
return suppFile(tete); // Exactement la même que suppfile donc on peut juste reutiliser la fonction
}
- On crée la fonction pour vérifier si la pile est triée par ordre croissant
1
2
3
4
5
6
7
8
9
10
11
12
13
int triCrepe(Pcrepe tete) {
if (tete == NULL || tete->next == NULL) {
return 1; // Une pile vide ou avec une seule crêpe est forcément triée
}
while (tete->next != NULL) {
if (tete->diametre > tete->next->diametre) {
return 0; // Si un diamètre est plus grand que le suivant, la pile n'est pas triée
}
tete = tete->next;
}
return 1;
}
- On crée la fonction pour inverser les M premiers éléments d’une pile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Pcrepe invCrepe(Pcrepe tete, int M) {
Pcrepe file = NULL;
Pcrepe temp = tete;
Pcrepe temp2;
int i = 0;
// Transférer les M premiers éléments dans une file
while (i < M && temp != NULL)
{
Pcrepe actual = (Pcrepe)malloc(sizeof(Crepe));
if (actual == NULL)
{
exit(EXIT_FAILURE);
}
actual->diametre = temp->diametre;
actual->next = NULL;
file = inserFile(file, actual);
temp = temp->next;
tete = suppPile(tete);
i++;
}
// Remettre les éléments de la file dans la pile pour les inverser
while (file != NULL) {
Pcrepe crepe = (Pcrepe)malloc(sizeof(Crepe));
if (crepe == NULL)
{
exit(EXIT_FAILURE);
}
crepe->diametre = file->diametre;
tete = inserPile(tete, crepe);
file = suppFile(file);
}
return tete;
}
- On crée la fonction pour trouver l’indice de la crêpe la plus grande dans une pile de taille M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int indMax(Pcrepe tete, int M) {
if (tete == NULL){
return -1;
}
int max = tete->diametre;
int index = 0;
int i = 0;
Pcrepe temp = tete;
// Parcourir la pile pour trouver le maximum
while (temp != NULL && i < M) {
if (temp->diametre > max) {
max = temp->diametre;
index = i;
}
i++;
temp = temp->next;
}
return index;
}
- On crée la fonction pour inverser les M premières crêpes où la plus grande se trouve
1
2
3
4
5
6
7
Pcrepe spatule(Pcrepe tete, int M) {
int index = indMax(tete, M);
tete = invCrepe(tete, index + 1);
tete = invCrepe(tete, M);
return tete;
}
- On crée la fonction principale pour trier les crêpes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void objectif(Pcrepe* tete) {
Pcrepe temp = *tete;
int taille = 0;
// Calculer la taille de la pile
while (temp != NULL) {
taille++;
temp = temp->next;
}
// Trier les crêpes en inversant les plus grandes à chaque itération
for (int i = taille; i > 1; i--) {
*tete = spatule(*tete, i);
}
}
- On teste le tout dans main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int main() {
// Exemple de pile de crêpes non triées
Pcrepe pile = NULL;
int tailles[] = {3, 6, 2, 9, 7, 4, 5};
for (int i = 6; i >= 0; i--) {
Pcrepe crepe = (Pcrepe)malloc(sizeof(Crepe));
if (crepe == NULL)
{
exit(EXIT_FAILURE);
}
crepe->diametre = tailles[i];
crepe->next = NULL;
pile = inserPile(pile, crepe); // Insérer chaque crêpe dans la pile
}
// Trier les crêpes
objectif(&pile);
// Affichage des crêpes triées
Pcrepe temp = pile;
printf("Crêpes triées par ordre croissant de diamètre:\n");
while (temp != NULL) {
printf("%d\n", temp->diametre); // Affichage de chaque crêpe triée
temp = temp->next;
}
return 0;
}
Cet article est sous licence BSD 2-Close licence par l'auteur.