Vous êtes sur la page 1sur 13

Les listes chanes

Les listes chanes


Les tableaux :
ont une taille fixe ;
occupent un espace contigu.

20

...

...

n-1 n

Indices :

Une liste chane est un ensemble dlments organiss squentiellement


20

lien

noeud
Ajouter un lment :

20

4
Supprimer un lment :

20

Benot Charroux - Listes chanes - Septembre 98 - 2

Inconvnient des listes chanes


Avec un tableau : accs direct un lment en connaissant son indice.

20

indice :

Avec une liste chane : parcourir la liste pour accder un lment.

20

Benot Charroux - Listes chanes - Septembre 98 - 3

Avantages des listes chanes


Avec un tableau : dplacer un lment dcalage.

20

Avec une liste chane : dplacer un lment modifier ses liens.

20

Ajout dun lment ;


Suppression dun lment.
Benot Charroux - Listes chanes - Septembre 98 - 4

Comment reprsenter les liens ?

20

Stocker un lien dans une case mmoire particulire : un pointeur

Un pointeur est une variable qui contient ladresse (lendroit o est rang en mmoire)
dune autre variable :
20

suivant = 100

6
100 : adresse

$OJRULWKPH
'pEXW
9DULDEOH

suivant: SRLQWHXUGH ...

)LQ

Benot Charroux - Listes chanes - Septembre 98 - 5

Comment reprsenter les liens et les nuds ?


Pour former une liste chane, tous nuds doit avoir un lien !
20

100

6
100

Regrouper nud et lien dans une structure denregistrement :


nud.h
#ifned __NUD_H
#define __NUD_H
typedef struct n{
int info ;
struct n* suivant ;
} NUD ;
#endif

Nimporte quel type de variables

/* __NUD_H */
Benot Charroux - Listes chanes - Septembre 98 - 6

Comment reprsenter les liens et les nuds ?


Le dernier nud doit avoir un lien !
Utiliser un nud factice qui pointe sur lui mme :
...

20
z

Utiliser un pointeur nul :


...

20

null

Pour mmoriser le dbut de la liste, on utilise parfois un nud factice :


20
dbut

Benot Charroux - Listes chanes - Septembre 98 - 7

Initialiser une liste chane

Initialiser une liste chane

ptrNoeud

null

NUD* initialiser(){
return NULL ;
}
void main(){
NUD* ptrNoeud ;
ptrNoeud = initialiser() ;
}

Benot Charroux - Listes chanes - Septembre 98 - 9

Initialiser une liste chane avec un nud factice au dbut


NUD* initialiser(){
NUD* ptrNoeud ;
ptrNoeud = (NUD*)malloc( sizeof( NUD ) ) ;
if( ptrNoeud != NULL ){
ptrNoeud->suivant = NULL ;
}
return ptrNoeud ;
dbut

}
void main(){
NUD* debut ;
debut = initialiser() ;
}

Benot Charroux - Listes chanes - Septembre 98 - 10

null

Initialiser une liste chane avec un nud factice au dbut et la fin


NUD* initialiser(){
NUD* z, *debut ;
z = (NUD*)malloc( sizeof( NUD ) ) ;
if( z != NULL ){
z->suivant = z ;
debut = (NUD*)malloc( sizeof( NUD ) ) ;
if( debut != NULL ){
debut->suivant = z ;
}
}
return debut ;
dbut
}
void main(){
NUD* debut ;
debut = initialiser() ;
}
Benot Charroux - Listes chanes - Septembre 98 - 11

Insrer dans une


liste chane

Insrer dans une liste chane avec un argument de type pointeur


NUD* insererEnTete( NUD* debut, int i ){
NUD* nouveau ;
nouveau = (NUD*)malloc( sizeof( NUD ) ) ;
if( nouveau != NULL ){
nouveau->suivant = debut ;
nouveau->info = i ;
}
return nouveau ;
}
void main(){
NUD* debut ;
debut = initialiser() ;
debut = insererEnTete( debut, 20 ) ;

debut

null

debut

20

null

}
Benot Charroux - Listes chanes - Septembre 98 - 13

Insrer dans une liste chane avec un argument de type


pointeur de pointeur

void main(){
NUD* debut ;
int res ;
debut = initialiser() ;
res = insererEnTete( GHEXW, 20 ) ;
}
LQW

debut

null

debut

20

insererEnTete( 18' debut, int i ){


NUD* nouveau ;
nouveau = (NUD*)malloc( sizeof( NUD ) ) ;
if( nouveau != NULL ){
nouveau->suivant = GHEXW ;
nouveau->info = i ;
GHEXW = nouveau ;
UHWXUQ

} else {
UHWXUQ

}
}

Benot Charroux - Listes chanes - Septembre 98 - 14

null

Insrer dans une liste chane avec un nud factice au dbut


int insererEnTete( NUD* debut, int i ){
NUD* nouveau ;
nouveau = (NUD*)malloc( sizeof( NUD ) ) ;
if( nouveau != NULL ){
nouveau->suivant = debut->suivant ;
nouveau->info = i ;
debut->suivant = nouveau ;
return 1 ;
} else {
null
return 0 ;
dbut
}
}
20
void main(){
dbut
NUD* debut ;
int res ;
debut = initialiser() ;
res = insererEnTete( debut, 20 ) ;
}

null

Benot Charroux - Listes chanes - Septembre 98 - 15

Insrer dans une liste chane avec un nud factice au dbut et la fin
La fonction prcdente est utilise puisquelle ne dpend que du premier nud :

int insererEnTete( NUD* debut, int i ){


NUD* nouveau ;
nouveau = (NUD*)malloc( sizeof( NUD ) ) ;
if( nouveau != NULL ){
nouveau->suivant = debut->suivant ;
nouveau->info = i ;
debut->suivant = nouveau ;
return 1 ;
} else {
dbut
z
return 0 ;
20
}
dbut
}
Benot Charroux - Listes chanes - Septembre 98 - 16

Rechercher dans
une liste chane

Rechercher un lment

NULL

dbut

Nud* recherchePrecedent( Nud* debut, int i ){


while( debut!=NULL && debut->info!=i ){
debut = debut ->suivant ;

/*tant que info du suivant i*/


/*continuer la recherche*/

}
return debut ;
}

Benot Charroux - Listes chanes - Septembre 98 - 18

Rechercher un lment dans un liste ayant un nud factice la fin

20
z

dbut

Nud* recherchePrecedent( Nud* debut, int i ){


while( debut->info != i ){
debut = debut ->suivant ;

/*tant que info du suivant i*/


/*continuer la recherche*/

}
return debut ;
}
Ce nest plus ncessaire de tester le fin de la liste.

Benot Charroux - Listes chanes - Septembre 98 - 19

Supprimer dans
une liste chane

Supprimer dans une liste chane


Supprimer un lment (30 par exemple) :
30
1

20

dbut

z
Pointer ici pour changer suivant.

Pour supprimer un lment il faut sarrter sur le prcdent :

30

20

dbut

Benot Charroux - Listes chanes - Septembre 98 - 21

Rechercher llment prcdant celui supprimer sans nud factice


30
NULL
Pointer ici pour changer suivant.
Nud* recherchePrecedent( Nud* debut, int i ){
if( debut !=NULL ){
if( debut->info == i ){

/* liste non vide */


/* si le premier est celui recherch */

return debut ;
}
while(debut->suivant!=NULL && debut ->suivant->info != i ){
debut = debut ->suivant ;
}
}
return debut ;
}
Benot Charroux - Listes chanes - Septembre 98 - 22

Rechercher llment prcdant celui supprimer


avec un nud factice au dbut
30
NULL
dbut
Pointer ici pour changer suivant.
Nud* recherchePrecedent( Nud* debut, int i ){
while( debut->suivant!=NULL && debut->suivant->info != i ){
debut = debut->suivant ;
}
return debut ;
}
Ce nest plus ncessaire de tester le dbut de la liste.
Benot Charroux - Listes chanes - Septembre 98 - 23

Rechercher llment prcdant celui supprimer


avec un nud factice au dbut et la fin

30
z

dbut
Nud* recherchePrecedent( Nud* debut, int i ){
while( debut->suivant->info != i ){
debut = debut->suivant ;
}
return debut ;
}

Ce nest plus ncessaire de tester ni le dbut, ni la fin de la liste.


Benot Charroux - Listes chanes - Septembre 98 - 24

Supprimer dans une liste chane

30
z

dbut
Pointer ici pour changer suivant.
void supprimerSuivant( NUD* n ){
Nud* tmp ;
tmp = n->suivant ;
n->suivant = n->suivant->suivant ;
free( tmp ) ;
}

/* mmorise le suivant */
/* pour le changer ici */
/* et le dtruire l */

Benot Charroux - Listes chanes - Septembre 98 - 25

Rechercher et supprimer dans une liste chan


ayant un nud factice au dbut et la fin

30
z

dbut

void supprimer( Nud* debut, int i ){


Nud* ptrPreced ;
ptrPreced = recherchePrcdent( debut, i ) ;
if( ptrPreced!=NULL && ptrPreced->suivant!=ptrPreced->suivant->suivant ){
supprimerSuivant( ptrPreced ) ;
}
}
Benot Charroux - Listes chanes - Septembre 98 - 26