• Aucun résultat trouvé

Exercice 4 : Listes doublement chaˆın´ ees

N/A
N/A
Protected

Academic year: 2022

Partager "Exercice 4 : Listes doublement chaˆın´ ees"

Copied!
5
0
0

Texte intégral

(1)

Isup 1 - Programmation TD no8 Matthieu Journault 19 juin 2020

Exercice 1 : Tableau dynamique

Dans cet exercice, il vous est demand´e d’implanter une structure de donn´ees permettant de stocker des entiers. Cette structure appel´ee tableau dynamique est repr´esent´ee par une structure C contenant 3 champs : un pointeur sur un tableau contenant les entiers ; un entier indiquant le nombre d’´el´ement stock´e dans le tableau et enfin un entier indiquant la taille allou´ee du tableau. Il est en effet possible que le tableau contienne moins d’´el´ement que sa taille allou´e. Lorsqu’un ´el´ement est ajout´e `a la collection :

— si le tableau est plein (le nombre d’´el´ements stock´es et la taille allou´ee sont les mˆemes), on alloue (avec malloc) un tableau deux fois plus grand, on recopie notre tableau dans le nouveau, on ajoute l’´el´ement dans le nouveau tableau puis on lib`ere l’ancien tableau.

— si le tableau n’est pas plein, on peut ajouter l’´el´ement dans le tableau existant.

Q. 1 D´efinir un type structur´e dynarray contenant : un pointeur content vers un tableau d’entier allou´e dans le tas, un entier size repr´esentant le nombre d’´el´ements dans la structure, un entier alloc repr´esentant la taille allou´ee pour le tableau content.

Q. 2D´efinir une fonctiondynarray empty();renvoyant un tableau vide.

Q. 3 D´efinir une fonction void print_dynarray(dynarray tab); permettant un affichage ´ecran du tableau pass´e en argument.

Q. 4D´efinir une fonction int is_in(dynarray tab, int e);permettant de tester l’appartenance de l’´el´ement e au tableau dynamique tab.

Q. 5 D´efinir une fonction void add(dynarray tab, int e); permettant l’ajout d’un ´el´ement `a la structure.

Q. 6D´efinir une fonctionvoid remove(dynarray tab, int e);permettant la suppression d’un ´el´ement de la structure.

Q. 7Pour la fonction main suivante : dynarray d = empty();

add(d, 0);

add(d, 1);

add(d, 2);

add(d, 3); /* 1 */

add(d, 4); /* 3 */

Repr´esenter l’´evolution de la m´emoire aux points 1, 2, 3 en supposant que le point 2 se trouve au milieu de votre fonctionadd, apr`es que le contenu du nouveau tableau a ´et´e rempli avec le contenu de l’ancien.

(2)

Exercice 2 : Listes chaˆın´ ees

Une liste est une structure de donn´ees qui repr´esente une collection de valeurs. L’un des int´erˆet des listes par rapport `a un tableau est qu’il est ais´e de supprimer ou ajouter des nouveaux ´el´ements entre les ´el´ements d´ej`a pr´esents dans la liste, ainsi que le fait que la taille d’une liste n’est pas strictement d´efinie `a sa cr´eation (et qu’elle peut donc changer au fil de l’ex´ecution du programme).

Le type d’une liste (simplement) chaˆın´ee qui contient des valeurs enti`eres peut ˆetre d´efini comme suit :

struct _int_list { int value;

struct _int_list* next;

};

Dans la suite, le type liste int sera un alias d’un pointeur vers unstruct int list : struct _int_list {

int value;

struct _int_list* next;

};

Chaque ´el´ement d’une liste simplement chaˆın´ee contient une valeur, et un pointeur vers la suite de la liste (i.e. l’´el´ement suivant).

Q. 8 Impl´ementer une fonction int_list push(int value, int_list list); qui permet d’ajouter un nouveau noeud dans une liste : L’astuce pour cr´eer une liste r´eduire `a un seul ´el´ement d’utiliser liste int liste = ajout debut(34,NULL) pour cr´eer une liste qui contient juste la valeur 34.

Q. 9Impl´ementer une fonction int_list empty();retournant la liste vide.

Q. 10 Impl´ementer une fonction int is_empty(int_list l); permettant de tester si une liste est vide.

Q. 11Afin de faciliter la manipulation des listes dans la suite d´efinir des macros :

— Cons(X, L) permettant de construire une liste ayant comme premi`ere valeur X et comme liste suivante X;

— Empty permettant de construire la liste vide ;

— Head(L) permettant de r´ecup´erer la valeur de l’´el´ement en tˆete de liste

— Tail(L) permettant de r´ecup´erer la sous liste des ´el´ements qui suive l’´el´ement en tˆete.

Q. 12Impl´ementer une version r´ecursive et une version it´erative de la fonctionvoid print_list(int_list list);

permettant l’affichage de la liste. Utiliser cette fonction et les macros d´efinies ci-avant pour v´erifier que vos fonctions fonctionnent.

Q. 13Impl´ementer une version r´ecursive et une version it´erative de la fonctionvoid free_list(int_list list);

permettant de lib´erer l’espace occup´e par la liste pass´ee en argument.

(3)

Q. 14 Impl´ementer une fonction r´ecursive int size_list(int_list list); calculant la taille d’une liste.

Q. 15Impl´ementer une fonctionint remove_index(int_list list, int i); permettant de suppri- mer l’´el´ement d’indice i de la liste list.

Q. 16On vous donne les trois fonctions suivantes calculant la concat´enation de deux listes.

int_list concatenation1(int_list l1, int_list l2) { if (is_empty(l1)) {return l2;}

else {

int_list ptr;

for (ptr = l1; ptr->next != NULL; ptr=ptr->next) {}

ptr->next = l2;

return l1;

} }

int_list concatenation2(int_list l1, int_list l2) { if (is_empty(l1) && is_empty(l2)) {return Empty;}

else if (is_empty(l1)) {return l2;}

else { return Cons(Head(l1), concatenation2(Tail(l1), l2)); } }

int_list concatenation3(int_list l1, int_list l2) { if (is_empty(l1) && is_empty(l2)) {return Empty;}

else if (is_empty(l1)) {return Cons(Head(l2), concatenation3(l1, Tail(l2)));}

else { return Cons(Head(l1), concatenation3(Tail(l1), l2)); } }

Pour chacune des trois fonctions donner une repr´esentation de la m´emoire au point de programme /* 1 */ en supposant que la fonction main soit la suivante :

int main() {

int_list l1 = Cons(1, Empty) ; int_list l2 = Cons(2, Empty) ;

int_list l = concatenation(l1, l2); /* 1 */

}

Q. 17D´efinir une fonction int_list reverse(int_list list); imp´erative inversant une liste.

Q. 18 D´efinir une fonction int_list rev_append(int_list list, int_list acc) r´ecursive retour- nant une copie du renversement de la listlist concat´en´e `a la liste acc.

Q. 19 En d´eduire une fonction int_list reverse2(int_list list) retournant une copie renvers´ee de la list list.

(4)

Exercice 3 : Tri fusion

Le tri fusion est un algorithme de tri fonctionnement r´ecursivement de la mani`ere suivante : Pour trier une liste de n´el´ements :

— s´eparer la liste en deux sous listes de mˆeme taille (`a 1 pr`es) ;

— trier r´ecursivement les deux sous listes ;

— fusionner intelligemment les deux sous listes ainsi tri´ees.

Ce que l’on entend par une fusion intelligente est : ´etant donn´e deux listes tri´ees on fusionne en produisant une liste tri´ee contenant tous les ´el´ements des deux sous listes. Une telle fusion peut ˆetre implant´ee assez facilement r´ecursivement en regardant uniquement les ´el´ements en tˆete des deux listes.

Q. 20Implanter une fonctionint_list split(int_list list);modifiant en place la listelistpour que celle-ci ne contienne plus qu’un ´el´ement sur deux de la liste list initial et retournant un pointeur vers une liste contenant les ´el´ements manquants.

Q. 21 Implanter une fonction int_list merge(int_list l1, int_list l2); prenant en argument deux listesl1 et l2 que vous supposerez tri´ees et modifiant ces deux listes en places pour produire une liste tri´ee contenant les ´el´ements de l1 etl2. Indication : proposer une d´efinition r´ecursive.

Q. 22En d´eduire une fonctionint_list sort(int_list l);triant une liste au moyen de l’algorithme de tri fusion propos´e ci-avant.

Exercice 4 : Listes doublement chaˆın´ ees

Nous avons vu qu’il ´etait difficile d’acc´eder aux derniers ´el´ements d’une liste chaˆın´ee (n´ecessit´e de parcourir toute la liste). Ceci peut ˆetre ennuyeux lorsqu’on aimerait avoir acc`es `a la fois au d´ebut et `a la fin d’une liste (par exemple pour repr´esenter une file d’attente o`u les gens entrent d’un cˆot´e et sortent de l’autre).

Dans cet exercice nous d´efinissons une nouvelle structure de donn´ee, les listes doublement chaˆın´ees permettant un acc`es `a la fois aux ´el´ements en tˆete et en fin de liste.

Une liste doublement chain´ees sera donc un pointeur vers une structure contenant : head un pointeur vers la tˆete de la liste ;

tail un pointeur vers la fin de la liste ;

De plus afin de faciliter la manipulation de la liste (par exemple, la suppression du dernier ´el´ement) il est important de garder en m´emoire l’´el´ement pr´ec´edant le dernier ´el´ement de la liste (sous peine d’avoir

`

a reparcourir toute la liste pour devoir trouver le nouveau dernier ´el´ement). Ainsi en plus de l’usuel pointeur vers le prochain ´el´ement de la liste nous devons garder un m´emoire pour chaque ´el´ement, un pointeur vers l’´el´ement le pr´ec´edant dans la liste. Ainsi chaque composante de notre liste aura :

elem un entier ;

prev un pointeur vers l’´el´ement de la liste qui le pr´ec`ede.

next un pointeur vers l’´el´ement de la liste qui le suit.

Ci-dessous une repr´esentation graphique d’une telle liste doublement chaˆın´ee contenant les ´el´ements 1,2,3 dans cet ordre.

(5)

0 NULL

elem prev next

1

elem prev next

2 NULL

elem prev next

head tail

Q. 23D´efinir la structurestruct dlistscontenant un entierelem, un pointeurprev vers unestruct dlists et un pointeur next vers unestruct dlists.

Q. 24 D´efinir le type dlist comme ´etant une structure contenant un pointeur head vers une struct dlist et un pointeur tail vers unestruct dlist.

Q. 25 D´efinir une fonction dlist empty(); renvoyant une dlist vide. La liste vide ne sera pas repr´esent´ee par un pointeur NULL mais par un pointeur vers une structure dont les deux champs head ettail sont des pointeurs NULL.

Q. 26D´efinir une fonction int is_empty(dlist dl); permettant de tester si une liste est vide.

Q. 27 D´efinir une fonction void print_dlist(dlist dl); permettant l’affichage de la liste pass´ee en argument.

Q. 28 D´efinir une fonction void push_head(int elem, dlist dl); permettant l’ajout en place d’un

´el´ement en tˆete de liste.

Q. 29D´efinir une fonctionint pop_head(int elem, dlist dl); permettant la suppression en place d’un ´el´ement en tˆete de liste, on retournera l’´el´ement ainsi supprim´e.

Q. 30 D´efinir une fonction void push_tail(int elem, dlist dl); permettant l’ajout en place d’un

´el´ement en fin de liste.

Q. 31D´efinir une fonctionint pop_tail(int elem, dlist dl); permettant la suppression en place d’un ´el´ement en fin de liste, on retournera l’´el´ement ainsi supprim´e.

Q. 32 D´efinir une fonctionvoid reverse(dlist dl);permettant de renverser en place la liste pass´ee en argument.

Q. 33D´efinir une fonctionvoid rem(dlist dl, int e); permettant la suppression de la valeur e de la listedl, on pourra supposer que e apparaˆıt au plus une fois dans dl.

Références

Documents relatifs

[r]

Deputy General Director, National Centre for Disease Control and Public Health, National Counterpart of Tobacco Control, Ministry of Labour, Health and Social Affairs.. Delegate(s)

1 D´ efinir un type structur´ e dynarray contenant : un pointeur content vers un tableau d’entier allou´ e dans le tas, un entier size repr´ esentant le nombre d’´ el´ ements

Dans le cas des pièces traitées avec des teintures, les possibles différences de couleur sont uniquement en raison de la nature du matériau, de sorte qu'en aucun cas cela pourra

HUMAN RIGHTS, JUSTICE AND LEGAL CO- OPERATION STANDARD SETTING ACTIVITIES DEPARTMENT / SERVICE DES ACTIVITÉS NORMATIVES EN MATIERE DE DROITS DE L’HOMME, JUSTICE

Adviser of the International Relations and Cooperation Division Department, Assembly of the Republic (SDP : Social Democratic Party / Parti social-démocrate). (PS :

,please check next page.... Pos

COORDINATING UNIT FOR THE MEDITERRANEAN ACTION PLAN PROGRAMME DES NATIONS UNIES POUR L'ENVIRONNEMENT. UNITE DE COORDINATION DU PLAN D'ACTION POUR