Les listes chanes Les tableaux : ont une taille fixe ; occupent un espace contigu. 20 6 1 ... 1 7 0 1 2 ... n-1 n Indices : Une liste chane est un ensemble dlments organiss squentiellement 20 6 1 1 7 noeud lien 20 6 1 1 7 4 20 6 1 7 Ajouter un lment : Supprimer un lment : Benot Charroux - Listes chanes - Septembre 98 - 3 Inconvnient des listes chanes Avec un tableau : accs direct un lment en connaissant son indice. 20 6 1 1 7 2 indice : Avec une liste chane : parcourir la liste pour accder un lment. 20 6 1 1 7 Benot Charroux - Listes chanes - Septembre 98 - 4 Avantages des listes chanes Avec un tableau : dplacer un lment dcalage. 20 6 1 1 7 Avec une liste chane : dplacer un lment modifier ses liens. 20 6 1 1 7 Ajout dun lment ; Suppression dun lment. Benot Charroux - Listes chanes - Septembre 98 - 5 Comment reprsenter les liens ? 6 20 Stocker un lien dans une case mmoire particulire : un pointeur suivant = 100 6 20 100 : adresse Un pointeur est une variable qui contient ladresse (lendroit o est rang en mmoire) dune autre variable : 1MMMV 1VM V suivant: @MMVM WV ... 1M Benot Charroux - Listes chanes - Septembre 98 - 6 Comment reprsenter les liens et les nuds ? Pour former une liste chane, tous nuds doit avoir un lien ! 100 6 20 100 Regrouper nud et lien dans une structure denregistrement : Nimporte quel type de variables #ifned __NUD_H #define __NUD_H typedef struct n{ int info ; struct n* suivant ; } NUD ; #endif /* __NUD_H */ nud.h Benot Charroux - Listes chanes - Septembre 98 - 7 Comment reprsenter les liens et les nuds ? Pour mmoriser le dbut de la liste, on utilise parfois un nud factice : Le dernier nud doit avoir un lien ! Utiliser un nud factice qui pointe sur lui mme : 20 ... z 20 dbut z Utiliser un pointeur nul : 20 ... null Initialiser une liste chane Benot Charroux - Listes chanes - Septembre 98 - 9 Initialiser une liste chane ptrNoeud null NUD* initialiser(){ return NULL ; } void main(){ NUD* ptrNoeud ; ptrNoeud = initialiser() ; } NUD* initialiser(){ NUD* ptrNoeud ; ptrNoeud = (NUD*)malloc( sizeof( NUD ) ) ; if( ptrNoeud != NULL ){ ptrNoeud->suivant = NULL ; } return ptrNoeud ; } void main(){ NUD* debut ; debut = initialiser() ; } Benot Charroux - Listes chanes - Septembre 98 - 10 Initialiser une liste chane avec un nud factice au dbut dbut null Benot Charroux - Listes chanes - Septembre 98 - 11 Initialiser une liste chane avec un nud factice au dbut et la fin dbut z 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 ; } void main(){ NUD* debut ; debut = initialiser() ; } Insrer dans une liste chane Benot Charroux - Listes chanes - Septembre 98 - 13 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 ) ; } null 20 debut null debut Benot Charroux - Listes chanes - Septembre 98 - 14 M insererEnTete( 11 debut, int i ){ NUD* nouveau ; nouveau = (NUD*)malloc( sizeof( NUD ) ) ; if( nouveau != NULL ){ nouveau->suivant = WVM ; nouveau->info = i ; WVM = nouveau ; VMM } else { VMM M } } null 20 debut null debut Insrer dans une liste chane avec un argument de type pointeur de pointeur void main(){ NUD* debut ; int res ; debut = initialiser() ; res = insererEnTete( WVM, 20 ) ; } Benot Charroux - Listes chanes - Septembre 98 - 15 Insrer dans une liste chane avec un nud factice au dbut dbut null 20 dbut null 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 { return 0 ; } } void main(){ NUD* debut ; int res ; debut = initialiser() ; res = insererEnTete( debut, 20 ) ; } Benot Charroux - Listes chanes - Septembre 98 - 16 Insrer dans une liste chane avec un nud factice au dbut et la fin dbut z 20 dbut z 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 { return 0 ; } } La fonction prcdente est utilise puisquelle ne dpend que du premier nud : Rechercher dans une liste chane Benot Charroux - Listes chanes - Septembre 98 - 18 Rechercher un lment Nud* recherchePrecedent( Nud* debut, int i ){ while( debut!=NULL && debut->info!=i ){ /*tant que info du suivant i*/ debut = debut ->suivant ; /*continuer la recherche*/ } return debut ; } 1 dbut NULL Benot Charroux - Listes chanes - Septembre 98 - 19 Rechercher un lment dans un liste ayant un nud factice la fin 20 dbut z Nud* recherchePrecedent( Nud* debut, int i ){ while( debut->info != i ){ /*tant que info du suivant i*/ debut = debut ->suivant ; /*continuer la recherche*/ } return debut ; } Ce nest plus ncessaire de tester le fin de la liste. Supprimer dans une liste chane Benot Charroux - Listes chanes - Septembre 98 - 21 Supprimer dans une liste chane Pour supprimer un lment il faut sarrter sur le prcdent : Supprimer un lment (30 par exemple) : 20 30 1 Pointer ici pour changer suivant. dbut z 20 30 1 dbut z Benot Charroux - Listes chanes - Septembre 98 - 22 Rechercher llment prcdant celui supprimer sans nud factice Nud* recherchePrecedent( Nud* debut, int i ){ if( debut !=NULL ){ /* liste non vide */ if( debut->info == i ){ /* si le premier est celui recherch */ return debut ; } while(debut->suivant!=NULL && debut ->suivant->info != i ){ debut = debut ->suivant ; } } return debut ; } 30 Pointer ici pour changer suivant. NULL Benot Charroux - Listes chanes - Septembre 98 - 23 Rechercher llment prcdant celui supprimer avec un nud factice au dbut 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. 30 Pointer ici pour changer suivant. dbut NULL Benot Charroux - Listes chanes - Septembre 98 - 24 Rechercher llment prcdant celui supprimer avec un nud factice au dbut et la fin 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. dbut 30 z Benot Charroux - Listes chanes - Septembre 98 - 25 Supprimer dans une liste chane void supprimerSuivant( NUD* n ){ Nud* tmp ; tmp = n->suivant ; /* mmorise le suivant */ n->suivant = n->suivant->suivant ; /* pour le changer ici */ free( tmp ) ; /* et le dtruire l */ } Pointer ici pour changer suivant. dbut 30 z Benot Charroux - Listes chanes - Septembre 98 - 26 Rechercher et supprimer dans une liste chan ayant un nud factice au dbut et la fin void supprimer( Nud* debut, int i ){ Nud* ptrPreced ; ptrPreced = recherchePrcdent( debut, i ) ; if( ptrPreced!=NULL && ptrPreced->suivant!=ptrPreced->suivant->suivant ){ supprimerSuivant( ptrPreced ) ; } } dbut 30 z