Sunteți pe pagina 1din 18

Gnralits sur les listes chaines

Lorsque vous crez un algorithme utilisant des conteneurs, il existe diffrentes manires de
les implmenter, la faon la plus courante tant les tableaux, que vous connaissez tous.
Lorsque vous crez un tableau, les lments de celui-ci sont placs de faon contigu en
mmoire. Pour pouvoir le crer, il vous faut connatre sa taille. Si vous voulez supprimer un
lment au milieu du tableau, il vous faut recopier les lments temporairement, r-allouer de
la mmoire pour le tableau, puis le remplir partir de l'lment supprim. En bref, ce sont
beaucoup de manipulations coteuses en ressources.
Une liste chane est diffrente dans le sens o les lments de votre liste sont rpartis dans la
mmoire et relis entre eux par des pointeurs. Vous pouvez ajouter et enlever des lments
d'une liste chane n'importe quel endroit, n'importe quel instant, sans devoir recrer la
liste entire.

Nous allons essayer de voir ceci plus en dtail sur ces schmas :



Vous avez sur ce schma la reprsentation que l'on pourrait faire d'un tableau et d'une liste
chane. Chacune de ces reprsentations possde ses avantages et inconvnients. C'est lors de
l'criture de votre programme que vous devez vous poser la question de savoir laquelle des
deux mthodes est la plus intressante.
Dans un tableau, la taille est connue, l'adresse du premier lment aussi. Lorsque vous
dclarez un tableau, la variable contiendra l'adresse du premier lment de votre
tableau.
Comme le stockage est contigu, et la taille de chacun des lments connue, il est
possible d'atteindre directement la case i d'un tableau.
Pour dclarer un tableau, il faut connatre sa taille.
Pour supprimer ou ajouter un lment un tableau, il faut crer un nouveau tableau et
supprimer l'ancien. Ce n'est en gnral pas visible par l'utilisateur, mais c'est ce que
realloc va souvent faire. L'adresse du premier lment d'un tableau peut changer aprs
un realloc, ce qui est tout fait logique puisque realloc n'aura pas forcement la
possibilit de trouver en mmoire la place ncessaire et contigu pour allouer votre
nouveau tableau. realloc va donc chercher une place suffisante, recopier votre tableau,
et supprimer l'ancien.

Dans une liste chane, la taille est inconnue au dpart, la liste peut avoir autant
d'lments que votre mmoire le permet.
Il est en revanche impossible d'accder directement l'lment i de la liste chaine.
Pour ce faire, il vous faudra traverser les i-1 lments prcdents de la liste.
Pour dclarer une liste chane, il suffit de crer le pointeur qui va pointer sur le
premier lment de votre liste chane, aucune taille n'est donc spcifier.
Il est possible d'ajouter, de supprimer, d'intervertir des lments d'une liste chane
sans avoir recrer la liste en entier, mais en manipulant simplement leurs pointeurs.


Chaque lment d'une liste chane est compos de deux parties :
la valeur que vous voulez stocker,
l'adresse de l'lment suivant, s'il existe.
S'il n'y a plus d'lment suivant, alors l'adresse sera NULL, et dsignera le bout de la
chane.

Voil deux schmas pour expliquer comment se passent l'ajout et la suppression d'un lment
d'une liste chane. Remarquez le symbole en bout de chane qui signifie que l'adresse de
l'lment suivant ne pointe sur rien, c'est--dire sur NULL.



Comme vous vous en doutez certainement maintenant, la liste chane est un type structur.
Nous en avons termin avec ces quelques gnralits, nous allons pouvoir passer la
dfinition d'une structure de donnes nous permettant de crer cette fameuse liste !
Vous pouvez essayer d'imaginer quoi va ressembler la structure liste_chainee : si vous avez
compris le principe, vous en tes capables. Je vous invite donc crire sur un papier vos ides
que vous pourrez ensuite comparer au rsultat que je vais fournir un peu plus bas !
Retour en haut
Dclaration en C d'une liste chaine
Vous vous demandez srement de quel type sera l'lment de la liste chane. A ceci je ne
peux rpondre que... vous de voir. En effet, vous pouvez crer des listes chanes de
n'importe quel type d'lments : entiers, caractres, structures, tableaux, voir mme d'autres
listes chanes... Il vous est mme possible de combiner plusieurs types dans une mme liste.
Allez : vous avez assez patient, voici la dclaration d'une liste simplement chane d'entiers :

Code : C - Slectionner
1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>

typedef struct element element;
struct element
{
int val;
struct element *nxt;
};

typedef element* llist;


On cre le type element qui est une structure contenant un entier (val) et un pointeur sur
lment (nxt), qui contiendra l'adresse de l'lment suivant. Ensuite, il nous faut crer le type
llist (pour linked list = liste chane) qui est en fait un pointeur sur le type element. Lorsque
nous allons dclarer la liste chane, nous devrons dclarer un pointeur sur element,
l'initialiser NULL, pour pouvoir ensuite allouer le premier lment. N'oubliez pas d'inclure
stdlib.h afin de pouvoir utiliser la macro NULL. Comme vous allez le constater, nous avons
juste cre le type llist afin de simplifier la dclaration.

Voil comment dclarer une liste chane (vide pour l'instant) :
Code : C - Slectionner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdlib.h>

typedef struct element element;
struct element
{
int val;
struct element *nxt;
};

typedef element* llist;



int main(int argc, char **argv)
{
/* Dclarons 3 listes chanes de faons diffrentes mais
quivalentes */
llist ma_liste1 = NULL;
element *ma_liste2 = NULL;
struct element *ma_liste3 = NULL;


return 0;
}

Il est important de toujours initialiser la liste chane NULL. Le cas chant, elle sera
considre comme contenant au moins un lment. C'est une erreur frquente. A garder en
mmoire donc. De manire gnrale, il est plus sage de toujours initialiser vos pointeurs.

Retour en haut
Manipuler les listes chaines (1/2)
Maintenant que nous savons comment dclarer une liste chane, il serait intressant
d'apprendre ajouter des lments dans cette liste, ainsi que de lire ce qu'elle contient. C'est
ce que nous allons tudier dans cette premire partie sur la manipulation des listes chanes.
Je vous invite essayer par vous-mmes de programmer ces quelques fonctions basiques
permettant de manipuler les listes. Dans tous les cas (ou presque), nous renverrons la nouvelle
liste, c'est--dire un pointeur sur element contenant l'adresse du premier lment de la liste.
Ajouter un lment


Lorsque nous voulons ajouter un lment dans une liste chane, il faut savoir o l'insrer. Les
deux ajouts gnriques des listes chanes sont les ajouts en tte, et les ajouts en fin de liste.
Nous allons tudier ces deux moyens d'ajouter un lment une liste.
Ajouter en tte


Lors d'un ajout en tte, nous allons crer un lment, lui assigner la valeur que l'on veut
ajouter, puis pour terminer, raccorder cet lment la liste passe en paramtre. Lors d'un
ajout en tte, on devra donc assigner nxt l'adresse du premier lment de la liste pass en
paramtre. Visualisons tout ceci sur un schma :



Code : C - Slectionner
1
2
3
4
5
6
llist ajouterEnTete(llist liste, int valeur)
{
/* On cre un nouvel lment */
element* nouvelElement = malloc(sizeof(element));

/* On assigne la valeur au nouvel lment */
7
8
9
10
11
12
13
14
nouvelElement->val = valeur;

/* On assigne l'adresse de l'lment suivant au nouvel lment */
nouvelElement->nxt = liste;

/* On retourne la nouvelle liste, i.e. le pointeur sur le premier
lment */
return nouvelElement;
}


C'est l'ajout le plus simple des deux. Il suffit de crer un nouvel lment puis de le relier au
dbut de la liste originale. Si l'original est , (vide) c'est NULL qui sera assigne au champ nxt
du nouvel element. La liste contiendra dans ce cas-l un seul lment.
Ajouter en fin de liste


Cette fois-ci, c'est un peu plus compliqu. Il nous faut tout d'abord crer un nouvel lment,
lui assigner sa valeur, et mettre l'adresse de l'lment suivant NULL. En effet,, comme cet
lment va terminer la liste nous devons signaler qu'il n'y a plus d'lment suivant. Ensuite, il
faut faire pointer le dernier lment de liste originale sur le nouvel lment que nous venons
de crer. Pour ce faire, il faut crer un pointeur temporaire sur element qui va se dplacer
d'lment en lment, et regarder si cet lment est le dernier de la liste. Un lment sera
forcment le dernier de la liste si NULL est assign son champ nxt.



Code : C - Slectionner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
llist ajouterEnFin(llist liste, int valeur)
{
/* On cre un nouvel lment */
element* nouvelElement = malloc(sizeof(element));

/* On assigne la valeur au nouvel lment */
nouvelElement->val = valeur;

/* On ajoute en fin, donc aucun lment ne va suivre */
nouvelElement->nxt = NULL;

if(liste == NULL)
{
/* Si la liste est vide il suffit de renvoyer l'lment cr */
return nouvelElement;
16
17
18
19
20
21
22
23
24
25
26
27
28
29
}
else
{
/* Sinon, on parcourt la liste l'aide d'un pointeur temporaire
et on
indique que le dernier lment de la liste est reli au nouvel
lment */
element* temp=liste;
while(temp->nxt != NULL)
{
temp = temp->nxt;
}
temp->nxt = nouvelElement;
return liste;
}
}

Comme vous pouvez le constater, nous nous dplaons le long de la liste chane grce au
pointeur temp. Si l'lment point par temp n'est pas le dernier (temp->nxt != NULL), on
avance d'un cran (temp = temp->nxt) en assignant temp l'adresse de l'lment suivant. Une
fois que l'on est au dernier lment, il ne reste plus qu' le relier au nouvel lment.

Si vous pensez avoir bien saisi ces deux fonctions, je vous invite passer la partie suivante,
dans laquelle je vais vous proposer quelques exercices. Le premier sera fondamental puisqu'il
nous permettra d'afficher le contenu d'une liste chane.
Retour en haut
Exercices (1/2)
Exercice n1

Vous allez maintenant pouvoir vous tester. Votre mission, si vous l'acceptez, est de coder la
fonction afficherListe. Vous devrez parcourir la liste jusqu'au bout et afficher toutes les
valeurs qu'elle contient. Voici son prototype :

Code : C - Slectionner
1 void afficherListe(llist liste);


Correction

Secret (cliquez pour afficher)





Exercice n2

Un deuxime exercice utilisant trois fonctions que nous avons vues jusqu' prsent :
ajouterEnTete
ajouterEnFin
afficherListe
Vous devez crire le main permettant de remplir et afficher la liste chane ci-dessous. Vous
ne devrez utiliser qu'une seule boucle for.

Code : Console - Slectionner
10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10

Aucune autre directive pour cet exercice qui ncessite peut-tre un peu de logique, mais
question technique vous devriez tre au point.


Correction

Secret (cliquez pour afficher)




Exercice n3

L'exercice suivant est le plus simple des trois, mais il me faut vous le montrer. crivez une
fonction qui renvoie 1 si la liste est vide, et 0 si elle contient au moins un lment. Son
prototype est le suivant :
Code : C - Slectionner
1 int estVide(llist liste);

Vous vous demandez srement l'intrt d'crire une telle fonction... eh bien quand vous codez
une bibliothque, le mieux est de "masquer" le fonctionnement interne de vos codes.
L'utilisateur n'est pas cens savoir qu'une liste vide sera gale NULL, ni mme que le type
llist est un pointeur. Lui, il dclare une llist sans savoir comment elle est cre, puis l'utilise
(ajoute ou supprime des lments, trie sa liste, etc...) grce aux fonctions de la bibliothque.
Dans certains cas, il lui faudra tester si la liste est vide, il utilisera par exemple :

Code : C - Slectionner
1
2
3
4
5
6
7
8
if(estVide(ma_liste))
{
printf("La liste est vide");
}
else
{
afficherListe(ma_liste);
}


A vous donc pour cette fonction !


Correction

Secret (cliquez pour afficher)







Nous voil au bout de cette premire srie d'exercices. Dans la section suivante, nous allons
voir plein de fonctions plus complexes permettant de manipuler nos listes chanes !
Retour en haut
Manipuler les listes chaines (2/2)
Cette fois, a va monter d'un cran niveau difficult. Nous allons voir tout un tas de fonctions,
pour supprimer des lments, rechercher un lment... Je vous conseille si vous n'avez pas
tout compris de revenir un peu en arrire, de faire des essais avec votre compilateur prfr,
parce que tout ce que nous allons voir fonctionne toujours sur le mme principe. Je
considrerais ce que j'ai prcdemment montr comme acquis. Cette partie va se drouler
comme ceci : j'explique l'algorithme gnral de la fonction puis je donne son code comment.

Prts ? On y va !
Supprimer un lment en tte


Il s'agit l de supprimer le premier lment de la liste. Pour ce faire, il nous faudra utiliser la
fonction free que vous connaissez certainement. Si la liste n'est pas vide, on stocke l'adresse
du premier lment de la liste aprs suppression (i.e. l'adresse du 2me lment de la liste
originale), on supprime le premier lment, et on renvoie la nouvelle liste. Attention quand
mme ne pas librer le premier lment avant d'avoir stock l'adresse du second, sans quoi il
sera impossible de la rcuprer.

Code : C - Slectionner
1
2
3
4
5
6
7
8
9
10
11
12
llist supprimerElementEnTete(llist liste)
{
if(liste != NULL)
{
/* Si la liste est non vide, on se prpare renvoyer l'adresse
de
l'lment en 2me position */
element* aRenvoyer = liste->nxt;
/* On libre le premier lment */
free(liste);
/* On retourne le nouveau dbut de la liste */
return aRenvoyer;
13
14
15
16
17
}
else
{
return NULL;
}
}


Supprimer un lment en fin de liste


Cette fois-ci, il va falloir parcourir la liste jusqu' son dernier lment, indiquer que l'avant-
dernier lment va devenir le dernier de la liste et librer le dernier lment pour enfin
retourner le pointeur sur le premier lment de la liste d'origine.

Code : C - Slectionner
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
llist supprimerElementEnFin(llist liste)
{
/* Si la liste est vide, on retourne NULL */
if(liste == NULL)
return NULL;

/* Si la liste contient un seul lment */
if(liste->nxt == NULL)
{
/* On le libre et on retourne NULL (la liste est maintenant
vide) */
free(liste);
return NULL;
}

/* Si la liste contient au moins deux lments */
element* tmp = liste;
element* ptmp = liste;
/* Tant qu'on n'est pas au dernier lment */
while(tmp->nxt != NULL)
{
/* ptmp stock l'adresse de tmp */
ptmp = tmp;
/* On dplace tmp (mais ptmp garde l'ancienne valeur de tmp */
tmp = tmp->nxt;
}
/* A la sortie de la boucle, tmp pointe sur le dernier lment, et
ptmp sur
l'avant-dernier. On indique que l'avant-dernier devient la fin de la
liste
et on supprime le dernier lment */
ptmp->nxt = NULL;
free(tmp);
return liste;
}


Rechercher un lment dans une liste


Le but du jeu cette fois est de renvoyer l'adresse du premier lment trouv ayant une certaine
valeur. Si aucun lment n'est trouv, on renverra NULL. L'intrt est de pouvoir, une fois le
premier lment trouv, chercher la prochaine occurrence en recherchant partir de
elementTrouve->nxt. On parcourt donc la liste jusqu'au bout, et ds qu'on trouve un lment
qui correspond ce que l'on recherche, on renvoie son adresse.

Code : C - Slectionner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
llist rechercherElement(llist liste, int valeur)
{
element *tmp=liste;
/* Tant que l'on n'est pas au bout de la liste */
while(tmp != NULL)
{
if(tmp->val == valeur)
{
/* Si l'lment a la valeur recherche, on renvoie son
adresse */
return tmp;
}
tmp = tmp->nxt;
}
return NULL;
}


Compter le nombre d'occurrences d'une valeur


Pour ce faire, nous allons utiliser la fonction prcdente permettant de rechercher un lment.
On cherche une premire occurrence : si on la trouve, alors on continue la recherche partir
de l'lment suivant, et ce tant qu'il reste des occurrences de la valeur recherche. Il est aussi
possible d'crire cette fonction sans utiliser la prcdente bien entendu, en parcourant
l'ensemble de la liste avec un compteur que l'on incrmente chaque fois que l'on passe sur
un lment ayant la valeur recherche. Cette fonction n'est pas beaucoup plus complique,
mais il est intressant d'un point de vue algorithmique de rutiliser des fonctions pour
simplifier nos codes.

Code : C - Slectionner
1
2
3
4
5
6
7
8
9
10
11
12
13
int nombreOccurences(llist liste, int valeur)
{
int i = 0;

/* Si la liste est vide, on renvoie 0 */
if(liste == NULL)
return 0;

/* Sinon, tant qu'il y a encore un lment ayant la val = valeur */
while((liste = rechercherElement(liste, valeur)) != NULL)
{
/* On incrmente */
liste = liste->nxt;
14
15
16
17
18
i++;
}
/* Et on retourne le nombre d'occurrences */
return i;
}


Recherche du i-me lment


Pour le coup, c'est une fonction relativement simple. Il suffit de se dplacer i fois l'aide du
pointeur tmp le long de la liste chane et de renvoyer l'lment l'indice i. Si la liste contient
moins de i lment(s), alors nous renverrons NULL.

Code : C - Slectionner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
llist element_i(llist liste, int indice)
{
int i;
/* On se dplace de i cases, tant que c'est possible */
for(i=0; i<indice && liste != NULL; i++)
{
liste = liste->nxt;
}

/* Si l'lment est NULL, c'est que la liste contient moins de i
lments */
if(liste == NULL)
{
return NULL;
}
else
{
/* Sinon on renvoie l'adresse de l'lment i */
return liste;
}
}


Rcuprer la valeur d'un lment


C'est une fonction du mme style que la fonction estVide. Elle sert "masquer" le
fonctionnement interne l'utilisateur. Il suffit simplement de renvoyer l'utilisateur la valeur
d'un lment. Il faudra renvoyer un code d'erreur entier si l'lment n'existe pas (la liste est
vide), c'est donc vous de dfinir une macro selon l'utilisation que vous voulez faire des listes
chanes. Dans ce code, je considre qu'on ne travaille qu'avec des nombres entiers positifs,
on renverra donc -1 pour une erreur. Vous pouvez mettre ici n'importe quelle valeur que vous
tes srs de ne pas utiliser dans votre liste. Une autre solution consiste renvoyer un pointeur
sur int au lieu d'un int, vous laissant donc la possibilit de renvoyer NULL.

Code : C - Slectionner
1
2
3
4
5
#define ERREUR -1
int valeur(llist liste)
{
return ((liste == NULL)?ERREUR:(liste->val));
}


Compter le nombre d'lments d'une liste chan


C'est un algorithme vraiment simple. Vous parcourez la liste de bout en bout et incrmentez
d'un pour chaque nouvel lment que vous trouvez. Cet algorithme n'ayant aucun intrt au
point o nous en sommes, je vais en profiter pour vous faire dcouvrir un nouveau type
d'algorithme. Jusqu' maintenant, nous n'avons utilis que des algorithmes itratifs qui
consistent boucler tant que l'on n'est pas au bout. Nous allons voir qu'il existe des
algorithmes que l'on appellent rcursifs et qui consistent en fait demander une fonction de
s'appeler elle-mme. Attention : il faudrait un big-tuto complet pour tout expliquer propos
des algorithmes rcursifs, ce n'est vraiment que pour vous montrer que ce genre de choses
existe que je vais les utiliser dans les deux prochains codes.

Avant tout, je pense qu'un petit point d'explication s'impose.
Pour crer un algorithme rcursif, il faut connatre la condition d'arrt (ou condition de sortie)
et la condition de rcurrence. Il faut en fait vous imaginer que votre fonction a fait son office
pour les n-1 lments suivants, et qu'il ne reste plus qu' traiter le dernier lment. Lisez le
code suivant. N'ayez pas peur si ceci vous semble obscur, ce n'est pas essentiel pour utiliser
les listes chanes. Maintenant, je suis sr que vous tes au point et vous pouvez donc de
manire itrative crer peu prs tout ce qui peut se faire.

Code : C - Slectionner
1
2
3
4
5
6
7
8
9
10
int nombreElements(llist liste)
{
/* Si la liste est vide, il y a 0 lment */
if(liste == NULL)
return 0;

/* Sinon, il y a un lment (celui que l'on est en train de traiter)
plus le nombre d'lments contenus dans le reste de la liste */
return nombreElements(liste->nxt)+1;
}


Effacer tous les lments ayant une certaine valeur


Pour cette dernire fonction, nous allons encore une fois utiliser un algorithme rcursif. Mme
si la rcursivit vous semble tre une notion complexe (et a l'est srement), elle simplifie
grandement les algorithmes dans certains cas, et dans celui-ci tout particulirement. Je vous
donne le code titre indicatif, vous pourrez vous mme recoder cette fonction avec un
algorithme itratif si vous le voulez.

Code : C - Slectionner
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
llist supprimerElement(llist liste, int valeur)
{
/* Liste vide, il n'y a plus rien supprimer */
if(liste == NULL)
return NULL;

/* Si l'lment en cours de traitement doit tre supprim */
if(liste->val == valeur)
{
/* On le supprime en prenant soin de mmoriser
l'adresse de l'lment suivant */
element* tmp = liste->nxt;
free(liste);
/* L'lment ayant t supprim, la liste commencera l'lment
suivant
pointant sur une liste qui ne contient plus aucun lment ayant
la valeur recherche */
tmp = supprimerElement(tmp, valeur);
return tmp;
}
else
{
/* Si l'lement en cours de traitement ne doit pas tre supprim,
alors la liste finale commencera par cet lment et suivra une
liste ne contenant
plus d'lment ayant la valeur recherche */
liste->nxt = supprimerElement(liste->nxt, valeur);
return liste;
}
}

Retour en haut
Exercices (2/2)
Exercice n1

Voil... Maintenant, vous tes des as en matire de liste chanes, j'en suis sr. Je vous
propose donc quelques exercices. Le premier sera de coder de manire itrative la fonction
nombreElements dont je vous rappelle le prototype :

Code : C - Slectionner
1 int nombreElements(llist liste);

C'est un exercice qui ne devrait pas vous poser de problmes : bonne chance.

Secret (cliquez pour afficher)




Exercice n2

Nous allons maintenant crire une fonction permettant d'effacer compltement une liste
chane de la mmoire. Je vous propose d'crire avec un algorithme itratif dans un premier
temps, puis une seconde fois grce un algorithme rcursif. Dans le premier cas, vous devez
parcourir la liste, stocker l'lment suivant, effacer l'lment courant et avancer d'une case. A
la fin la liste est vide, nous retournerons NULL.

Secret (cliquez pour afficher)



Et voil : vous en savez maintenant un peu plus sur ce que sont les listes chanes. Vous
pourrez amliorer ceci en utilisant les listes doublement chanes, qui sont en fait une liste
d'lments qui pointent la fois sur l'lment suivant, mais aussi sur l'lment prcdent, ce
qui vous permet de revenir en arrire plus facilement qu'avec les listes simplement chanes.
Vous pouvez complter votre bibliothque avec des fonctions de tri, de recherche de
minimum, de maximum et bien d'autre choses...

Passons maintenant un petit QCM, afin de vrifier que vous avez tout saisi !
Retour en haut
Q.C.M.
Le premier QCM de ce cours vous est offert en libre accs.
Pour accder aux suivants
Connectez-vous Inscrivez-vous
Une erreur s'est glisse dans le code suivant :
Code : C - Slectionner
1
2
3
4
5
6
typedef struct element element;
struct element
{
int val;
struct element nxt;
};
Il manque un typedef
Il manque une toile
Le code est juste
J'excute le programme contenant le main suivant, que va-t-il se passer ?

Code : C - Slectionner
1 int main(int argc, char **argv)
2
3
4
5
6
7
{
element* ma_liste;
ma_liste = ajouterEnTete(ma_liste, 12);
afficherListe(ma_liste);
return 0;
}
Rien du tout
a ne compile pas : tu as mis element* la place de llist pour dclarer ma_liste
Une erreur de segmentation
Statistiques de rponses au QCM
Retour en haut
Eh bien il semblerait que vous tes au point. Comme vous avez pu le constater, le choix
d'utiliser ou non les listes chanes est fait lors de l'implmentation de votre algorithme dans
un langage. Vous devrez toujours faire des compromis.

J'avais parl d'introduire les listes doublement chanes, ce que je vais faire maintenant pour
vous permettre d'aller plus loin. L'ide est la suivante : un lment ne va plus se composer
d'une valeur et d'une adresse, mais d'une valeur et de deux adresses : l'adresse de l'lment
suivant mais aussi l'adresse de l'lment prcdent. On pourra tirer avantage de cette
spcificit pour lire des listes l'envers. Avoir l'adresse de l'lment prcdent peut simplifier
les algorithmes de vos fonctions, mais tout aussi bien les compliquer car c'est maintenant
deux pointeurs qu'il faut grer lors d'un ajout ou d'une suppression.

Nous sommes loin d'avoir cod une bibliothque complte, mais vos connaissances vous
permettent maintenant de continuer seuls et d'implmenter toutes sortes de fonctions.


Merci d'avoir lu ce tutoriel jusqu'au bout. Si une ou plusieurs erreurs s'y sont glisses (ce n'est
pas exclu), prvenez-moi par MP.
Remerciements Nicolas et Mleg pour avoir vrifi, test ce tutoriel et permis de ce fait sa
parution.

Je sais que le sujet des listes chaines est souvent abord lors de l'entre dans les tudes
suprieures, aussi je serais ravis d'apprendre qu'un professeur vous a redirig sur mon
tutoriel, si tel est le cas n'hsitez pas me le faire savoir par message !


A bientt !
Retour en haut
Partager


Retour en haut
112 commentaires pour "Les listes chanes"
Note moyenne : 3.67 / 4 (36 votes)
Pseudo Commentaire
lexou # Post le 29/08/2012 00:40:47


Oui l'attribut nxt du dernier noeud contient bien la valeur null, mais si tu
regardes la condition, c'est tmp qu'on compare, et pas tmp->nxt. Tmp
represente l'element courant.

Lorsqu'on parcours le dernier element, tmp pointe sur celui ci, on affiche sa
valeur, puis tmp devient tmp->nxt et donc null. Tmp n'est plus alors un
element contenant une valeur a afficher.

Lexou pour vous servir...

b_reda31 # Post le 29/08/2012 03:03:59

Avis : Trs bon
Aah oui merci, je sais pas pourquoi j'ai lu :
while (Tmp->nxt!=NULL)

je pense avoir confondu avec la boucle d'un autre exercice.
bref tout s'explique maintenant. Merci encore lexou.
TwisterJ # Post le 11/11/2012 02:39:01
tudes : IUT
Nancy-
Charlemagne
Bonjour tout le monde,

juste parfait ton cours lexou

J'aurais un petit claircissement demander !!

Tout d'abord, je voudrais tre sur que liste est bien un pointeur implicite sur
element dfinit par le "typedef element* llist;", est-ce bien a ?

par contre et malgr que j'ai assimil en me disant que c'est comme a, je
ne comprends pas rellement dans la fonction "ajouterEnTete" la ligne
suivante:

/* On assigne l'adresse de l'lment suivant au nouvel lment */
nouvelElement->nxt = liste;

J'ai compris partiellement que liste est une adresse. Et que cette adresse est
assigne nouvelElement->nxt.
La ou je coince, est pourquoi crit-on:
nouvelElement->nxt = liste;
et non pas:
nouvelElement->nxt = &(liste);

car habituellement lorsque nous assignons une adresse un pointeur qui en
loccurrence ici est nouvelElement->nxt, nous mettons le symbole &, alors
Pseudo Commentaire
qu'ici, j'ai l'impression qu'on lui fournit une valeur.

exemple:
int a;
int liste* = &a;

ici, si je voulais que liste me donne l'adresse de a. On ferait simplement:
liste et non pas *liste.

J'espre que vous me comprendrez
Merci d'avance.
Cdl,
Twister.
lexou # Post le 12/11/2012 00:59:48


En gros, le typedef veut dire : crire "llist" est quivalent crire
"element*" dans le code. Si remplacer tous les llist par element* peut
t'aider, alors n'hsites pas

Une liste est reprsente par l'adresse de son premier lment. C'est donc
un pointeur, dans le code il est de type element* ou llist, c'est exactement la
mme chose. Le typedef n'est la que pour diffrencier l'utilisation en temps
que liste, ou l'utilisation en temps que noeud ou lment de la liste.

Dans la ligne : nouvelElement->nxt = liste;
on assigne au nouvel lment que l'on vient de crer, l'adresse de l'lment
qui va le suivre. Lors d'un ajout en tte, c'est l'adresse du premier lment
de la liste actuelle, et par rapport au paragraphe si dessus, c'est donc la liste
actuelle, vu que celle ci est reprsente par ce mme premier lment.

Si tu analyse la struct dfinie au dbut, tu constatera que nxt est de type
element*. Et comme element* est quivalent llist, il est tout fait logique
que l'on puisse assigner la variable liste passe en paramtre nxt vu
qu'elle est de type element*.

Si tu remplaces toutes les occurences de "llist" par "element*" tout sera
surement plus clair.

Bon courage !

Lexou pour vous servir...

TwisterJ # Post le 13/11/2012 01:43:06
tudes : IUT
Nancy-
Charlemagne
Excellent, je vois parfaitement comment le visualiser.

Merci d'avoir us de ton temps pour me rpondre
hh tu fais un heureux l !!

Pseudo Commentaire
Bonne continuation et merci pour ce tuto.

Cdl,
TwisterJ.

S-ar putea să vă placă și