Listes chainées¶
Lire cette page
On se donne une structure de liste chaînée de données de type int définie ainsi :
Exercice 1¶
Écrire une fonction List empty_list () qui renvoie la valeur de
pointeur que vous aurez choisie pour représenter la liste vide, puis la
fonction Boolean is_empty (List l) qui teste si une liste est vide
(vous devrez définire le type Boolean, avec une enum).
Exercice 2¶
Écrire deux fonctions d'affichage des éléments d'une liste. L'une itérative, l'autre récursive.
Exercice 3¶
Écrire une fonction List add_first(int data, List l) qui
renvoie une liste ayant comme premier élément data et dont la suite est
constituée par la liste l ainsi que la fonction List remove_first(List l) qui prend une liste non vide l, lui enlève sa tête
et renvoie la suite de la liste.
Assurez vous que toute la mémoire allouée par X appels à add_first soit libérée par X appels à remove_first.
Ecrire une fonction main() pour tester votre code.
Exercice 4¶
Changez les signatures de add_first et remove_first pour que le code suivant (à completer) fonctionne comme attendu :
List l = empty_list();
int i;
for(i=5;i>0;i--)
add_first(i,/* a completer */);
print_list(l); /* affiche 1 2 3 4 5*/
for(i=0;i<5;i++)
remove_first(/* a completer */);
if(is_empty(l)) printf("la liste est vide\n");
Exercice 5¶
Écrire une fonction void free_list(List * l) qui libère toute la mémoire
occupée par une liste l. Pourquoi la liste est-elle passée par adresse ?
en remplacant la boucle du code précédant par un appel à free_list, le comportement du programme ne doit pas changer.
Exercice 6¶
Écrire une fonction Cell* get(int v, List * l) qui
enlève la première occurrence de v dans la liste l passée par adresse.
La mémoire associée au maillon enlevé ne doit pas être libéré, en revanche un pointeur vers ce maillon est renvoyé.
Ecire ensuite une fonction List add_cell(Cell* c, List * l); qui ajoute le maillon c passé par addresse à la fin de la liste l passée par adresse.
Testez le code :
List l = empty_list();
List l2 = empty_list();
int i;
for(i=5;i>0;i--)
add_first(i,/* a completer */);
print_list(l); /* affiche 1 2 3 4 5*/
for(i=1;i<=5;i++)
add_cell(get(1,&l),&l2);
if(is_empty(l)) printf("la liste l est vide\n");
print_list(l2);
Application au mini projet¶
Nous allons modifier le mini projet pour que le serpent ne stocke plus ses positions dans un tableau mais dans une liste chainée de positions.
- modifiez le type Position pour que la structure contienne un pointeur next
- modifiez le type Snake pour remplacer le tableau de position par un pointeur vers une Position que vous appelerez segments_list
- ajoutez aussi un champs entier size
- ecrivez une fonction new_snake qui renvoit un nouveau serpent alloué dynamiquement dans lequel le champs size est à 0 et le champs segments_list est à NULL
- ecrivez une fonction add_segment qui prend en paramètre un pointeur de Snake et deux entiers x et
y,
- créée une Position à partir de x et y, allouée dynamiquement et dont le champs next est à NULL
- ajoute cette Position en queue de la liste des segments
- ecrivez une fonction free_snake qui libère toute la mémoire associée à un serpent
- modifiez le reste de votre code en conséquence pour qu'il marche comme avant avec ces modifications sur le type Snake. N'oubliez pas d'utiliser new_snake et free_snake
Rendu¶
N'oubliez pas de pousser votre travail sur gitlab !
Dans un répertoire nommé login_tp6 copiez vos .c, makefile et .h. Vous pouvez y ajouter un fichier texte README si vous avez des choses à expliquer à joindre à votre rendu. Depuis le répertoire parent, tapez la commande tar czf login_tp6.tgz login_tp6. Déposez sur blackboard le fichier obtenu.