Vous êtes sur la page 1sur 15

Chapitre 14

Listes chan es e
14.1 La notion de liste
Une liste est une structure de donn es qui permet de stocker une s quence dobjets dun m me e e e type. En cela, les listes ressemblent aux tableaux. La s quence dentiers 3, 7, 2, 4 peut etre repr sent e e e e a la fois sous forme de tableau ou de liste. La notation [3, 7, 2, 4] repr sentera la liste qui contient ` e cette s quence. e Il y a cependant des diff rences fondamentales entre listes et tableaux : e Dans un tableau on a acc` s imm diat a nimporte quel el ment par son indice (acc` s dit al atoire), e e ` e e e tandis que dans une liste chan e on a acc` s aux el ments un apr` s lautre, a partir du premier e e e e ` el ment (acc` s dit s quentiel). e e e Un tableau a une taille xe, tandis quune liste peut augmenter en taille ind niment (on peut e toujours rajouter un el ment a une liste). e ` D nition (r cursive) : e e En consid rant que la liste la plus simple est la liste vide (not e [ ]), qui ne contient aucun el ment, e e e on peut donner une d nition r cursive aux listes chan es d l ments de type T : e e e ee la liste vide [ ] est une liste ; si e est un el ment de type T et l est une liste d l ments de type T, alors le couple (e, l) est e ee aussi une liste, qui a comme premier el ment e et dont le reste des el ments (` partir du second) e e a forment la liste l. Cette d nition est r cursive, car une liste est d nie en fonction dune autre liste. Une telle e e e d nition r cursive est correcte, car une liste est d nie en fonction dune liste plus courte, qui contient e e e un el ment de moins. Cette d nition permet de construire nimporte quelle liste en partant de la liste e e vide. Conclusion : la liste chan e est une structure de donn es r cursive. e e e La validit de cette d nition r cursive peut etre discut e dun point de vue diff rent. Elle peut e e e e e etre exprim e sous la forme suivante : quelque soit la liste l consid r e, e ee soit l est la liste vide [ ], soit l peut etre d compos e en un premier el ment e et un reste r de la liste, l=(e, r). e e e Cette d nition donne une d composition r cursive des listes. La condition g n rale darr t de e e e e e e r cursivit est pour la liste vide. Cette d composition est valide, car la liste est r duite a chaque pas e e e e ` a une liste plus courte dune unit . Cela garantit que la d composition m` ne toujours a une liste de ` e e e ` longueur 0, la liste vide (condition darr t). e 1

CHAPITRE 14. LISTES CHAINEES

14.2 Repr sentation des listes chan es en Java e e


Il y a plusieurs facons de repr senter les listes chan es en Java. Lid e de base est dutiliser un e e e enchanement de cellules : chaque cellule contient un el ment de la liste ; e chaque cellule contient une r f rence vers la cellule suivante, sauf la derni` re cellule de la liste ee e (qui contient une r f rence nulle) ; ee la liste donne acc` s a la premi` re cellule, le reste de la liste est accessible en passant de cellule e ` e en cellule, suivant leur enchanement. La gure 14.1 illustre cette repr sentation pour la liste exemple ci-dessus [3, 7, 2, 4]. e

liste

F IG . 14.1 Repr sentation par enchanement de cellules de la liste [3, 7, 2, 4] e En Java, les r f rences ne sont pas d nies explicitement, mais implicitement a travers les objets : ee e ` un objet est repr sent par une r f rence vers la zone de m moire qui contient ses variables dinstance. e e ee e Comme une liste est d nie par une r f rence vers une cellule (la premi` re de la liste), la m thode e ee e e la plus simple est de repr senter une liste par sa premi` re cellule. La classe suivante d nit une liste e e e dentiers. Listing 14.1 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 class Liste { int element ; Liste suivant ; L i s t e ( i nt premier , L i s t e r e s t e ){ element = premier ; suivant = reste ; } }

Le constructeur de la classe Liste cr e une liste comme une premi` re cellule qui contient le e e premier el ment de la liste et une r f rence vers le reste de la liste. e ee Remarque : Cette solution a linconv nient de ne repr senter que des listes avec au moins une cele e lule. La liste vide, qui selon la d nition est egalement une liste, ne peut pas etre un objet de e la classe Liste. Il est n anmoins possible de repr senter la liste vide par une r f rence nulle. e e ee Cette repr sentation imparfaite des listes a lavantage de la simplicit et nous lutiliserons dans e e le reste de ce cours.

14.3 Op rations sur les listes chan es e e


Nous etudierons les op rations les plus importantes sur les listes chan es, qui seront repr sent es e e e e comme des m thodes de la classe Liste. e Remarque : Puisque la classe Liste ne peut pas repr senter la liste vide, des op rations de base e e comme le test de liste vide ou laction de vider une liste ne peuvent pas etre des m thodes de la e

14.3. OPERATIONS SUR LES LISTES CHAINEES

classe Liste. Ces op rations doivent etre effectu es a lext rieur de la classe Liste, par le e e ` e programme qui utilise les listes. Conform ment a leur d nition, les listes sont des structures r cursives. Par cons quent, les e ` e e e op rations sur les listes sexpriment naturellement par des algorithmes r cursifs. En m me temps, e e e les listes sont des structures lin aires, parfaitement adapt es a un parcours it ratif. Nous donnerons e e ` e aussi la variante it rative des op rations sur listes, a titre comparatif. e e ` La repr sentation de la classe Liste ci-dessous montre sous forme de m thodes les op rations e e e sur listes que nous discuterons. Listing 14.2 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Liste { int element ; Liste suivant ; public L i s t e ( i nt premier , L i s t e r e s t e ){ element = premier ; suivant = reste ; } public public public public public public public public public } int premier ( ) { . . . } Liste reste ( ) { . . . } v o i d m o d i f i e P r e m i e r ( i n t elem ) { . . . } void m o d i f i e R e s t e ( L i s t e r e s t e ) { . . . } int longueur ( ) { . . . } b o o l e a n c o n t i e n t ( i n t elem ) { . . . } L i s t e i n s e r t i o n D e b u t ( i n t elem ) { . . . } void c o n c a t e n a t i o n ( L i s t e l i s t e ) { . . . } L i s t e s u p p r e s s i o n P r e m i e r ( i n t elem ) { . . . }

14.3.1 Op rations sans parcours de liste e


Pour ces op rations il ny a pas de variantes it ratives et r cursives, laction est r alis e directee e e e e ment sur la t te de la liste. e e Obtenir le premier el ment et le reste de la liste Ces op rations sont r alis es par les m thodes premier (qui retourne le premier el ment de la e e e e e liste), respectivement reste (qui retourne le reste de la liste). En fait, ces m thodes ne sont pas n cessaires, au sens strict du terme, puisque dans la classe e e Liste on a acc` s direct aux variables dinstance element et suivant. e Nous verrons plus tard que lacc` s direct aux variables dinstance est d conseill dans la programe e e mation orient e-objet. A la place, on pr ferre cacher les variables dinstance et donner acc` s a leur e e e ` valeurs a travers des m thodes. Ceci fera lobjet dun prochain cours. ` e Aussi, ces m thodes correspondent aux el ments de la d composition r cursive dune liste et sont e e e e bien adapt es a l criture dalgorithmes r cursifs sur les listes. e ` e e Listing 14.3 (lien vers le code brut)
1 public int premier (){

4
2 3 4 5 6 7 return element ; } public Liste r e s t e (){ return s u i v a n t ; }

CHAPITRE 14. LISTES CHAINEES

Remarque : Il ne faut pas oublier que premier et reste sont des m thodes de la classe Liste, e donc une instruction comme return element signie return this.element. Une liste est repr sent e par sa premi` re cellule, donc return this.element retourne l l ment e e e ee de cette premi` re cellule. e e Modier le premier el ment et le reste de la liste Ces op rations sont r alis es par les m thodes modifiePremier (qui modie le premier el ment e e e e e de la liste), respectivement modifieReste (qui modie le reste de la liste). Ces m thodes permettent donc de modier les composants element et suivant de la premi` re e e cellule de la liste. Elles sont compl mentaires aux m thodes premier et reste, qui permettent de e e consulter ces m mes composants. e Leur pr sence dans la classe Liste correspond au m me principe que celui evoqu pour premier e e e et reste : remplacer lacc` s direct aux variables dinstance par des appels de m thodes. e e Listing 14.4 (lien vers le code brut)
1 2 3 4 5 6 7 p u b l i c v o i d m o d i f i e P r e m i e r ( i n t elem ) { e l e m e n t = elem ; } public void m o d i f i e R e s t e ( L i s t e r e s t e ){ suivant = reste ; }

e Ins rer un el ment en t te de liste e e Linsertion en t te de liste est r alis e par la m thode insertionDebut. Cest une op ration e e e e e simple, car elle n cessite juste un acc` s a la t te de la liste initiale. On cr e une nouvelle cellule, a e e ` e e ` laquelle on enchane lancienne liste. La m thode insertionDebut retourne une nouvelle liste, car la liste initiale est modi e par e e linsertion (la premi` re cellule de la nouvelle liste est diff rente). e e Listing 14.5 (lien vers le code brut)
1 2 3 p u b l i c L i s t e i n s e r t i o n D e b u t ( i n t elem ) { r e t u r n new L i s t e ( elem , t h i s ) ; }

14.3.2 Op rations avec parcours de liste - variante it rative e e


Ces op rations n cessitent un parcours complet ou partiel de la liste. Dans la variante it rative, e e e le parcours est r alis a laide dune r f rence qui part de la premi` re cellule de la liste et suit lene e` ee e chanement des cellules.

14.3. OPERATIONS SUR LES LISTES CHAINEES


La gure 14.2 illustre le principe du parcours it ratif dune liste a laide dune r f rence ref. e ` ee

ref liste

........

ref

e1

...

ei

...

en

F IG . 14.2 Parcours it ratif dune liste a laide dune r f rence e ` ee

Calculer la longueur dune liste Cette op ration, r alis e par la m thode longueur, n cessite un parcours complet de la liste e e e e e pour compter le nombre de cellules trouv es. e Listing 14.6 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 public int longueur (){ i n t compteur = 0 ; Liste ref=this ; while ( r e f != n u l l ){ c o m p t e u r ++; ref=ref . reste (); / / ou r e f = r e f . s u i v a n t } return compteur ; }

Remarque : La r f rence ref est positionn e au d but sur la premi` re cellule de la liste et avance ee e e e jusqu` ce quelle devient nulle a la n de la liste. Chaque fois quelle pointe vers une nouvelle a ` cellule, le compteur est incr ment . Remarquez que lavancement dans la liste se fait en utilie e sant la m thode reste de la cellule courante, ou sinon lacc` s direct a la variable dinstance e e ` suivant. e ` V rier lappartenance dun el ment a une liste e Cette op ration, r alis e par la m thode contient, n cessite un parcours partiel de la liste pour e e e e e chercher l l ment en question. Si l l ment est retrouv , le parcours sarr te a ce moment-l` , sinon il ee ee e e ` a continue jusqu` la n de la liste. a Listing 14.7 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 p u b l i c b o o l e a n c o n t i e n t ( i n t elem ) { Liste ref=this ; while ( r e f != n u l l ){ i f ( r e f . p r e m i e r ( ) == elem ) / / ou r e f . e l e m e n t==e l e m return true ; / / l element a ete retrouve else ref=ref . reste (); / / ou r e f = r e f . s u i v a n t } return f a l s e ; / / l element n a pas e t e r e t r o u v e }

CHAPITRE 14. LISTES CHAINEES

Remarque : Larr t du parcours en cas de succ` s se fait en retournant directement true pendant e e lex cution de la boucle, ce qui termine a la fois la boucle et la fonction. Remarquez que le test e ` de l l ment courant point par la r f rence utilise la m thode premier de la cellule courante, ee e ee e ou sinon lacc` s direct a la variable dinstance element. e ` Concat nation de deux listes e Cette op ration, r alis e par la m thode concatenation, rajoute a la n de la liste courante e e e e ` toutes les cellules de la liste pass e en param` tre. Elle n cessite un parcours complet de la liste coue e e rante, an de trouver sa derni` re cellule. e La liste obtenue par concat nation a toujours la m me premi` re cellule que la liste initiale. On e e e peut dire donc que la liste initiale a et modi e, en lui rajoutant par concat nation une autre liste. e e e Listing 14.8 (lien vers le code brut)
1 2 3 4 5 6 7 8 public void c o n c a t e n a t i o n ( L i s t e Liste ref=this ; while ( r e f . r e s t e ( ) != n u l l ){ ref=ref . reste (); } / / re f pointe maintenant sur la ref . modifieReste ( l i s t e ) ; } l i s t e ){ / / ou r e f . s u i v a n t != n u l l / / ou r e f = r e f . s u i v a n t d e r n i e r e c e l l u l e de l a l i s t e / / ou r e f . s u i v a n t= l i s t e

Remarque : La condition de la boucle while change ici, car on veut sarr ter sur la derni` re cellule et e e non pas la d passer comme dans les m thodes pr c dentes. Remarquez que lenchanement des e e e e deux listes se fait en modiant la variable dinstance suivant de la derni` re cellule a laide e ` de la m thode modifieReste, ou sinon par modication directe de celle-ci. e e Suppression de la premi` re occurrence dun el ment e Cette op ration, r alis e par la m thode suppressionPremier, elimine de la liste la premi` re e e e e e apparition de l l ment donn en param` tre (sil existe). La m thode retourne une liste, car la liste ee e e e obtenue par suppression peut avoir une autre premi` re cellule que la liste initiale. Ceci arrive quand la e cellule elimin e est exactement la premi` re de la liste. e e La suppression dune cellule de la liste se fait de la mani` re suivante (voir la gure 14.3) : e si la cellule est la premi` re de la liste, la nouvelle liste sera celle qui commence avec la seconde e cellule. sinon la cellule a un pr d cesseur ; pour eliminer la cellule il faut la court-circuiter, en moe e diant la variable suivant du pr d cesseur pour quelle pointe vers la m me chose que la e e e variable suivant de la cellule.

pred liste

ref liste

pred

ref

e2

...

e1

...

ei

...

nouvelle liste
F IG . 14.3 Suppression dune cellule de la liste

14.3. OPERATIONS SUR LES LISTES CHAINEES

Le parcours de la liste a la recherche de l l ment donn a une particularit : si la r f rence ` ee e e ee sarr te sur la cellule qui contient l l ment, la suppression nest plus possible, car on na plus acc` s e ee e au pr d cesseur (dans les listes chan es on ne peut plus revenir en arri` re). e e e e La m thode utilis e est alors de parcourir la liste avec deux r f rences : e e ee une (ref) qui cherche la cellule a eliminer ; ` une autre (pred) qui se trouve toujours sur le pr d cesseur de ref. e e Listing 14.9 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 p u b l i c L i s t e s u p p r e s s i o n P r e m i e r ( i n t elem ) { Liste ref=this ; / / r e f e r e n c e qui cherche elem L i s t e pred= null ; / / predecesseur , i n i t i a l i s e a nu l l w h i l e ( r e f ! = n u l l && r e f . p r e m i e r ( ) ! = elem ) { / / r e c h e r c h e elem pred = r e f ; / / avance pred ref = ref . reste (); / / avance r e f } i f ( r e f != n u l l ){ / / elem t r o u v e dans l a c e l l u l e r e f i f ( p r e d == n u l l ) / / p r e m i e r e c e l l u l e de l a l i s t e return r e f . r e s t e ( ) ; / / r e t o u r n e l e r e s t e de l a l i s t e else { / / m i l i e u de l a l i s t e p r e d . m o d i f i e R e s t e ( r e f . r e s t e ( ) ) ; / / m o d i f i e l e s u i v a n t du p r e d e c e s s e u r return t h i s ; / / p r e m i e r e c e l l u l e non m o d i f i e e } } e l s e return t h i s ; / / e l e m e n t non t r o u v e }

14.3.3 Op rations avec parcours de liste - variante r cursive e e


Ces op rations sont bas es sur une d composition r cursive de la liste en un premier el ment et e e e e e le reste de la liste (voir la gure 14.4). Le cas le plus simple (condition darr t) est la liste avec une e seule cellule.

liste

premier reste

...

F IG . 14.4 D composition r cursive dune liste e e

Calcul r cursif de la longueur dune liste e La formule r cursive est : e liste.longueur() = 1 si reste==null 1 + reste.longueur() si reste!=null La fonction r cursive longueur s crit alors tr` s facilement, comme suit : e e e Listing 14.10 (lien vers le code brut)
1 public int longueur (){

8
2 3 4 5 6

CHAPITRE 14. LISTES CHAINEES


Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; i f ( r e s t e L i s t e == n u l l ) / / condition d arret return 1; e l s e return 1 + r e s t e L i s t e . longueur ( ) ;

` V rication r cursive de lappartenance a une liste e e La formule r cursive est : e liste.contient(e) = true si premier==e false si premier!=e et reste==null reste.contient(e) si premier!=e et reste!=null Remarquez que dans ce cas il y a deux conditions darr t : quand on trouve l l ment recherch ou e ee e quand la liste na plus de suite (reste est vide). La fonction r cursive contient s crit alors comme e e suit : Listing 14.11 (lien vers le code brut)
1 2 3 4 5 6 7 p u b l i c b o o l e a n c o n t i e n t ( i n t elem ) { i f ( elem == p r e m i e r ( ) ) r e t u r n t r u e ; / / ou e l e m==e l e m e n t Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; i f ( r e s t e L i s t e == n u l l ) / / condition d arret return f a l s e ; e l s e r e t u r n r e s t e L i s t e . c o n t i e n t ( elem ) ; }

Concat nation r cursive de deux listes e e Laction r cursive est : e liste.concatenation(l): reste=l si reste==null reste.concatenation(l) si reste!=null Si la liste a une seule cellule (pas de cellule suivante, reste est vide), alors il faut modier la r f rence vers la cellule suivante pour enchaner la liste param` tre. Sinon, il suft de concat ner le ee e e reste avec la liste param` tre. e Listing 14.12 (lien vers le code brut)
1 2 3 4 5 6 public void c o n c a t e n a t i o n ( L i s t e l i s t e ){ Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; i f ( r e s t e L i s t e == n u l l ) / / condition d arret modifieReste ( l i s t e ) ; / / ou s u i v a n t= l i s t e else resteListe . concatenation ( l i s t e ); }

14.3. OPERATIONS SUR LES LISTES CHAINEES


e Suppression r cursive de la premi` re occurrence dun el ment e e La formule r cursive est : e

liste.suppressionPremier(e) = reste si premier==e Liste(premier, null) si premier!=e et reste==null Liste(premier, reste.suppressionPremier(e)) si premier!=e et reste != null Si le premier el ment de la liste est celui recherch , le r sultat sera le reste de la liste. Sinon, il e e e faut supprimer r cursivement l l ment recherch du reste. Mais le r sultat de cette suppression est e ee e e une liste qui provient de reste, donc elle na plus le premier el ment de la liste initiale. Il faut donc le e rajouter en t te de liste. e Listing 14.13 (lien vers le code brut)
1 2 3 4 5 6 7 p u b l i c L i s t e s u p p r e s s i o n P r e m i e r ( i n t elem ) { Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; i f ( elem == p r e m i e r ( ) ) / / ou e l e m==e l e m e n t return r e s t e L i s t e ; e l s e i f ( r e s t e L i s t e == n u l l ) r e t u r n new L i s t e ( p r e m i e r ( ) , n u l l ) ; e l s e r e t u r n new L i s t e ( p r e m i e r ( ) , r e s t e L i s t e . s u p p r e s s i o n P r e m i e r ( elem ) ) ; }

Remarque : Linconv nient de cette m thode est quon cr e des copies de toutes les cellules qui ne e e e contiennent pas l l ment recherch . Pour eviter cela, la d nition doit m langer calcul et effets ee e e e de bord, comme suit : liste.suppressionPremier(e) = reste si premier==e liste si premier!=e et reste==null liste apr`s laction reste=reste.suppressionPremier(e) e si premier!=e et reste!=null

Listing 14.14 (lien vers le code brut)


1 2 3 4 5 6 7 8 9 10 p u b l i c L i s t e s u p p r e s s i o n P r e m i e r ( i n t elem ) { Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; i f ( elem == p r e m i e r ( ) ) / / ou e l e m==e l e m e n t return r e s t e L i s t e ; e l s e i f ( r e s t e L i s t e == n u l l ) r e t u r n t h i s ; else { m o d i f i e R e s t e ( r e s t e L i s t e . s u p p r e s s i o n P r e m i e r ( elem ) ) ; return t h i s ; } }

10

CHAPITRE 14. LISTES CHAINEES

14.4 Listes tri es e


Nous nous int ressons maintenant aux listes chan es dans lesquelles les el ments respectent un e e e ordre croissant. Dans ce cas, les m thodes de recherche, dinsertion et de suppression sont diff rentes. e e Lordre des el ments permet darr ter plus t t la recherche dun el ment qui nexiste pas dans la liste. e e o e Aussi, linsertion ne se fait plus en d but de liste, mais a la place qui pr serve lordre des el ments. e ` e e Nous utiliserons une classe ListeTriee qui est tr` s similaire a la classe Liste, mais dans lae ` quelle on sint resse uniquement aux m thodes de recherche (contientTriee), dinsertion (insertionTriee) e e et de suppression (suppressionTriee). Les autres m thodes sont identiques a celles de la classe e ` Liste. Listing 14.15 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class ListeTriee { int element ; ListeTriee suivant ; public L i s t e T r i e e ( i nt premier , L i s t e T r i e e r e s t e ){ element = premier ; suivant = reste ; } public public public public int premier ( ) { . . . } ListeTriee reste ( ) { . . . } v o i d m o d i f i e P r e m i e r ( i n t elem ) { . . . } void m o d i f i e R e s t e ( L i s t e T r i e e r e s t e ) { . . . }

p u b l i c b o o l e a n c o n t i e n t T r i e e ( i n t elem ) { . . . } p u b l i c L i s t e T r i e e i n s e r t i o n T r i e e ( i n t elem ) { . . . } p u b l i c L i s t e T r i e e s u p p r e s s i o n T r i e e ( i n t elem ) { . . . } }

14.4.1 Recherche dans une liste tri e e


La diff rence avec la m thode contient de Liste est que dans le parcours de la liste on peut e e sarr ter d` s que la cellule courante contient un el ment plus grand que celui recherch . Comme tous e e e e les el ments suivants vont en ordre croissant, ils seront egalement plus grands que l l ment recherch . e ee e Variante iterative : Listing 14.16 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 p u b l i c b o o l e a n c o n t i e n t T r i e e ( i n t elem ) { ListeTriee ref=this ; w h i l e ( r e f ! = n u l l && r e f . p r e m i e r ( ) <= elem ) { i f ( r e f . p r e m i e r ( ) == elem ) return true ; else ref=ref . reste (); } return f a l s e ; }

14.4. LISTES TRIEES


Variante r cursive : e Listing 14.17 (lien vers le code brut)
1 2 3 4 5 6 7 8 p u b l i c b o o l e a n c o n t i e n t T r i e e ( i n t elem ) { i f ( elem == p r e m i e r ( ) ) r e t u r n t r u e ; i f ( elem < p r e m i e r ( ) ) r e t u r n f a l s e ; ListeTriee resteListe = reste () ; i f ( r e s t e L i s t e == n u l l ) return f a l s e ; e l s e r e t u r n r e s t e L i s t e . c o n t i e n t T r i e e ( elem ) ; }

11

14.4.2 Insertion dans une liste tri e e


Linsertion dun el ment doit se faire a la bonne place dans la liste. La bonne place est juste avant e ` la premi` re cellule qui contient un el ment plus grand que celui a ins rer. e e ` e Variante iterative : La gure 14.5 montre les deux cas dinsertion : en d but de liste. e Elle est similaire alors a lop ration insertionDebut de la classe Liste ` e en milieu de liste. La recheche de la position dinsertion se fait alors avec une m thode similaire a celle utie ` lis e pour la m thode suppressionPremier de la classe Liste, avec deux r f rences. e e ee Le pr d cesseur doit etre modi pour pointer vers la nouvelle cellule, tandis que celle-ci doit e e e pointer vers la cellule courante (ref).
pred liste nouvelle liste ref liste pred ref

e1

...

e1

...

ep e

er

...

F IG . 14.5 Insertion dans une liste tri e e Dans la gure 14.5, a droite, la r f rence ref peut ne pas pointer vers une cellule. Ceci arrive quand ` ee l l ment a ins rer est plus grand que tous les el ments de la liste. Dans ce cas, linsertion se fait a ee ` e e ` la n de la liste, donc au moment de larr t de la recherche, ref est nulle et pred est sur la derni` re e e cellule de la liste. Ce cas est identique a celui pr sent dans la gure 14.5, a la variable suivant de ` e e ` la nouvelle cellule on donne tout simplement la valeur de ref. Listing 14.18 (lien vers le code brut)
1 2 3 4 5 6 p u b l i c L i s t e T r i e e i n s e r t i o n T r i e e ( i n t elem ) { ListeTriee ref=this ; / / r e f e r e n c e qui cherche elem L i s t e T r i e e pred= null ; / / predecesseur , i n i t i a l i s e a nu l l w h i l e ( r e f ! = n u l l && r e f . p r e m i e r ( ) < elem ) { / / recherche position pred = r e f ; / / avance pred ref = ref . reste (); / / avance r e f

12
7 8 9 10 11 12 13 14 15

CHAPITRE 14. LISTES CHAINEES


} i f ( p r e d == n u l l ) / / i n s e r t i o n au d e b u t r e t u r n new L i s t e T r i e e ( elem , t h i s ) ; else { / / i n s e r t i o n au m i l i e u de l a l i s t e L i s t e T r i e e n o u v eau = new L i s t e T r i e e ( elem , r e f ) ; p r e d . m o d i f i e R e s t e ( n o u v eau ) ; / / m o d i f i e l e s u i v a n t du p r e d e c e s s e u r return t h i s ; / / p r e m i e r e c e l l u l e non m o d i f i e e }

Variante r cursive : e Nous utilisons le m me sch ma de d composition r cursive de la liste, en un premier el ment e e e e e (premier) et un reste de la liste (reste). Linsertion r cursive suit le sch ma suivant : e e liste.insertionTriee(e) = ListeTriee(e, liste) si e<=premier liste apr`s reste=ListeTriee(e, null) e si e>premier et reste==null liste apr`s reste=reste.insertionTriee(e) si e>premier et reste!=null e Si l l ment a ins rer est plus petit ou egal a premier, linsertion se fera en t te de liste. Sinon, ee ` e ` e linsertion se fera r cursivement dans le reste. Si reste est vide, alors reste sera remplac par la nouvelle e e cellule a ins rer. Si reste nest pas vide, linsertion se fait r cursivement dans reste et le r sultat ` e e e remplace lancien reste. Listing 14.19 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 10 11 12 p u b l i c L i s t e T r i e e i n s e r t i o n T r i e e ( i n t elem ) { i f ( elem <= p r e m i e r ( ) ) r e t u r n new L i s t e T r i e e ( elem , t h i s ) ; else { ListeTriee resteListe = reste (); i f ( r e s t e L i s t e == n u l l ) m o d i f i e R e s t e ( new L i s t e T r i e e ( elem , n u l l ) ) ; else m o d i f i e R e s t e ( r e s t e L i s t e . i n s e r t i o n T r i e e ( elem ) ) ; return t h i s ; } }

14.4.3 Suppression dans une liste tri e e


La suppression de la premi` re occurrence dun el ment dans une liste tri e est assez similaire e e e a la suppression dans une liste non tri e. La seule chose qui change est la recherche de la cellule a ` e ` supprimer, qui b n cie du tri des valeurs. Aussi, si plusieurs occurrences de l l ment existent, elles e e ee sont forc ment lune a la suite de lautre a cause du tri. Il serait donc plus simple d liminer toutes les e ` ` e occurrences de l l ment que dans le cas des listes non tri es. Nous nous limiterons cependant ici a la ee e ` suppression de la premi` re occurrence seulement. e Variante iterative :

14.5. UN EXEMPLE DE PROGRAMME QUI UTILISE LES LISTES

13

Par rapport a la m thode suppressionPremier de la classe Liste, ici le parcours de la ` e liste a la recherche de l l ment ne se fait que tant que ref pointe une valeur plus petite que celui-ci. ` ee Une fois le parcours arr t , la seule diff rence est quil faut v rier que ref pointe vraiment la valeur ee e e recherch e. e Listing 14.20 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 p u b l i c L i s t e s u p p r e s s i o n T r i e e ( i n t elem ) { Liste ref=this ; / / r e f e r e n c e qui cherche elem L i s t e pred= null ; / / predecesseur , i n i t i a l i s e a nu l l w h i l e ( r e f ! = n u l l && r e f . p r e m i e r ( ) < elem ) { / / r e c h e r c h e elem pred = r e f ; / / avance pred ref = ref . reste (); / / avance r e f } i f ( r e f ! = n u l l && r e f . p r e m i e r ( ) == elem ) { / / e l e m t r o u v e d a n s l a c e l l u l e r e f i f ( p r e d == n u l l ) / / p r e m i e r e c e l l u l e de l a l i s t e return r e f . r e s t e ( ) ; / / r e t o u r n e l e r e s t e de l a l i s t e else { / / m i l i e u de l a l i s t e p r e d . m o d i f i e R e s t e ( r e f . r e s t e ( ) ) ; / / m o d i f i e l e s u i v a n t du p r e d e c e s s e u r return t h i s ; / / p r e m i e r e c e l l u l e non m o d i f i e e } } e l s e return t h i s ; / / e l e m e n t non t r o u v e }

Variante r cursive : e Par rapport a la variante r cursive de la m thode suppressionPremier de la classe Liste, ` e e une nouvelle condition darr t est rajout e : e e quand l l ment a eliminer est plus petit que premier, il nexiste s rement pas dans la liste et celle-ci ee ` u est retourn e non modi e. e e Listing 14.21 (lien vers le code brut)
1 2 3 4 5 6 7 8 9 10 11 p u b l i c L i s t e s u p p r e s s i o n T r i e e ( i n t elem ) { Liste resteListe = reste () ; i f ( elem == p r e m i e r ( ) ) return r e s t e L i s t e ; e l s e i f ( elem < p r e m i e r ( ) ) r e t u r n t h i s ; / / nouvelle condition d arret e l s e i f ( r e s t e L i s t e == n u l l ) r e t u r n t h i s ; else { m o d i f i e R e s t e ( r e s t e L i s t e . s u p p r e s s i o n T r i e e ( elem ) ) ; return t h i s ; } }

14.5 Un exemple de programme qui utilise les listes


Consid rons un exemple simple de programme qui manipule des listes chan es en utilisant la e e classe Liste.

14

CHAPITRE 14. LISTES CHAINEES

Le programme lit une suite de nombres entiers termin e par la valeur 0 et construit une liste avec e ces entiers (sauf le 0 nal). La liste doit garder les el ments dans lordre dans lequel ils sont introduits. e Egalement, une valeur ne doit etre stock e quune seule fois dans la liste. e Le programme lit ensuite une autre suite de valeurs, egalement termin e par un 0, avec lesquelles e il construit une autre liste, sans se soucier de lordre des el ments. Les el ments de cette seconde liste e e devront etre elimin s de la liste initiale. e A la n, le programme afche ce qui reste de la premi` re liste. e Remarque : Pour garder les el ments dans lordre dintroduction, linsertion dun nouvel el ment e e doit se faire en n de liste. La m thode insertionDebut ne convient donc pas. La solution e est dutiliser la m thode concatenation. e Remarque : Pour quun el ment soit stock une seule fois dans la liste, il faut dabord v rier sil e e e ny est pas d j` , a laide de la m thode contient. ea ` e Voici le programme qui r alise ces actions : e Listing 14.22 (lien vers le code brut)
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 33 34 35 public cl as s ExempleListes{ p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { / / 1. Creation premiere l i s t e T e r m i n a l . e c r i r e S t r i n g l n ( E n t r e z l e s v a l e u r s t e r m i n e e s p a r un 0 : ) ; Liste l i s t e = null ; / / l i s t e a construire do { i nt val = Terminal . l i r e I n t ( ) ; i f ( v a l ==0) break ; i f ( l i s t e == n u l l ) l i s t e = new L i s t e ( v a l , n u l l ) ; else i f (! l i s t e . contient ( val )) l i s t e . c o n c a t e n a t i o n ( new L i s t e ( v a l , n u l l ) ) ; } while ( true ) ; / / 2. Creation seconde l i s t e T e r m i n a l . e c r i r e S t r i n g l n ( V a l e u r s a e l i m i n e r ( t e r m i n e e s p a r un 0 ) : ) ; Liste l i s t e 2 = null ; do { i nt val = Terminal . l i r e I n t ( ) ; i f ( v a l ==0) break ; i f ( l i s t e 2 == n u l l ) l i s t e 2 = new L i s t e ( v a l , n u l l ) ; else l i s t e 2 = l i s t e 2 . insertionDebut ( val ) ; } while ( true ) ; / / 3 . E l i m i n a t i o n de l a p r e m i e r e l i s t e f o r ( L i s t e r e f = l i s t e 2 ; r e f != n u l l ; r e f = r e f . r e s t e ( ) ) { i f ( l i s t e == n u l l ) break ; / / plus rien a eliminer l i s t e = l i s t e . suppressionPremier ( r ef . premier ( ) ) ; } / / 4. Affichage l i s t e restante Terminal . e c r i r e S t r i n g l n ( Valeurs r e s t a n t e s : ) ; f o r ( L i s t e r e f = l i s t e ; r e f != n u l l ; r e f = r e f . r e s t e ( ) ) Terminal . e c r i r e S t r i n g ( + r e f . premier ( ) ) ;

14.5. UN EXEMPLE DE PROGRAMME QUI UTILISE LES LISTES


36 37 38 Terminal . sautDeLigne ( ) ; } }

15