SlideShare ist ein Scribd-Unternehmen logo
1 von 15
Downloaden Sie, um offline zu lesen
Chapitre 14

Listes chaˆn´ es
          ı e

14.1 La notion de liste
    Une liste est une structure de donn´ es qui permet de stocker une s´ quence d’objets d’un mˆ me
                                            e                              e                            e
type. En cela, les listes ressemblent aux tableaux. La s´ quence d’entiers 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 n’importe quel el´ ment par son indice (acc` s dit al´ atoire),
                                  e       e   `                ´e                            e      e
       tandis que dans une liste chaˆn´ e on a acc` s aux el´ ments un apr` s l’autre, a partir du premier
                                       ı e         e       ´e              e           `
       el´ ment (acc` s dit s´ quentiel).
       ´e            e       e
    – Un tableau a une taille fixe, tandis qu’une liste peut augmenter en taille ind´ finiment (on peut
                                                                                        e
       toujours rajouter un el´ ment a une liste).
                              ´e       `
D´ finition (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´ finition r´ cursive aux listes chaˆn´ 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´ finition est r´ cursive, car une liste est d´ finie en fonction d’une autre liste. Une telle
            e               e                                e
d´ finition r´ cursive est correcte, car une liste est d´ finie en fonction d’une liste plus courte, qui contient
 e          e                                          e
un el´ ment de moins. Cette d´ finition permet de construire n’importe quelle liste en partant de la liste
    ´e                          e
vide.
Conclusion : la liste chaˆn´ e est une structure de donn´ es r´ cursive.
                         ı e                            e e
     La validit´ de cette d´ finition r´ cursive peut etre discut´ e d’un 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´ finition donne une d´ composition r´ cursive des listes. La condition g´ n´ rale d’arrˆ 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 d’une unit´ . Cela garantit que la d´ composition m` ne toujours a une liste de
`                                      e                      e                 e              `
longueur 0, la liste vide (condition d’arrˆ t).
                                           e

                                                      1
2                                                                                          ˆ ´
                                                                        CHAPITRE 14. LISTES CHAINEES

    14.2 Repr´ sentation des listes chaˆn´ es en Java
             e                         ı e
       Il y a plusieurs facons de repr´ senter les listes chaˆn´ es en Java. L’id´ e de base est d’utiliser un
                            ¸            e                     ı e                  e
    enchaˆnement 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 enchaˆnement.
                                          ı
       La figure 14.1 illustre cette repr´ sentation pour la liste exemple ci-dessus [3, 7, 2, 4].
                                           e

                            liste
                                              3             7          2           4
                 F IG . 14.1 – Repr´ sentation par enchaˆnement de cellules de la liste [3, 7, 2, 4]
                                   e                    ı

        En Java, les r´ f´ rences ne sont pas d´ finies 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 d’instance.
                     e      e         ee                          e
        Comme une liste est d´ finie 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´ finit une liste
                                e                               e                                e
    d’entiers.
                                        Listing 14.1 – (lien vers le code brut)
1   class Liste {
2     int element ;
3     Liste suivant ;
4
5       L i s t e ( i nt premier , L i s t e r e s t e ){
6           element = premier ;
7           suivant = reste ;
8       }
9   }

       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 l’inconv´ nient de ne repr´ senter que des listes avec au moins une cel-
                                          e                  e
        lule. La liste vide, qui selon la d´ finition 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 l’avantage de la simplicit´ et nous l’utiliserons dans
                   e                                                            e
        le reste de ce cours.


    14.3 Op´ rations sur les listes chaˆn´ es
           e                           ı e
       Nous etudierons les op´ rations les plus importantes sur les listes chaˆn´ 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 l’action de vider une liste ne peuvent pas etre des m´ thodes de la
                                                                                  ˆ         e
´                          ˆ ´
     14.3. OPERATIONS SUR LES LISTES CHAINEES                                                                    3

            classe Liste. Ces op´ rations doivent etre effectu´ es a l’ext´ rieur de la classe Liste, par le
                                  e               ˆ           e `         e
            programme qui utilise les listes.
          Conform´ ment a leur d´ finition, les listes sont des structures r´ cursives. Par cons´ quent, les
                    e       `        e                                            e                 e
     op´ rations sur les listes s’expriment 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   class Liste {
 2     int element ;
 3     Liste suivant ;
 4
 5       public L i s t e ( i nt premier , L i s t e r e s t e ){
 6         element = premier ;
 7         suivant = reste ;
 8       }
 9
10       public    int premier ( ) { . . . }
11       public    Liste reste ( ) { . . . }
12       public    v o i d m o d i f i e P r e m i e r ( i n t elem ) { . . . }
13       public    void m o d i f i e R e s t e ( L i s t e r e s t e ) { . . . }
14       public    int longueur ( ) { . . . }
15       public    b o o l e a n c o n t i e n t ( i n t elem ) { . . . }
16       public    L i s t e i n s e r t i o n D e b u t ( i n t elem ) { . . . }
17       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 ) { . . . }
18       public    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 ) { . . . }
19   }


     14.3.1 Op´ rations sans parcours de liste
              e
        Pour ces op´ rations il n’y a pas de variantes it´ ratives et r´ cursives, l’action est r´ alis´ e directe-
                       e                                 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 d’instance element et suivant.
                       e
          Nous verrons plus tard que l’acc` s direct aux variables d’instance est d´ conseill´ dans la program-
                                             e                                     e         e
     mation orient´ e-objet. A la place, on pr´ ferre “cacher” les variables d’instance et donner acc` s a leur
                    e                            e                                                      e `
     valeurs a travers des m´ thodes. Ceci fera l’objet d’un prochain cours.
               `               e
          Aussi, ces m´ thodes correspondent aux el´ ments de la d´ composition r´ cursive d’une liste et sont
                       e                              ´e               e            e
     bien adapt´ es a l’´ criture d’algorithmes r´ cursifs sur les listes.
                 e ` e                             e

                                            Listing 14.3 – (lien vers le code brut)
1    public int premier (){
4                                                                                              ˆ ´
                                                                            CHAPITRE 14. LISTES CHAINEES

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

    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 signifie 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
    Modifier le premier el´ ment et le reste de la liste
        Ces op´ rations sont r´ alis´ es par les m´ thodes modifiePremier (qui modifie le premier el´ ment
                e               e e               e                                              ´e
    de la liste), respectivement modifieReste (qui modifie le reste de la liste).
        Ces m´ thodes permettent donc de modifier 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 l’acc` s direct aux variables d’instance par des appels de m´ thodes.
                                  e                                                   e
                                            Listing 14.4 – (lien vers le code brut)
1   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 ) {
2      e l e m e n t = elem ;
3   }
4
5   public void m o d i f i e R e s t e ( L i s t e r e s t e ){
6     suivant = reste ;
7   }


       e        ´e
    Ins´ rer un el´ ment en tˆ te de liste
                             e
        L’insertion en tˆ te de liste est r´ alis´ e par la m´ thode insertionDebut. C’est 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 enchaˆne l’ancienne liste.
                       ı
        La m´ thode insertionDebut retourne une nouvelle liste, car la liste initiale est modifi´ e par
              e                                                                                           e
    l’insertion (la premi` re cellule de la nouvelle liste est diff´ rente).
                          e                                        e
                                            Listing 14.5 – (lien vers le code brut)
1   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 ) {
2      r e t u r n new L i s t e ( elem , t h i s ) ;
3   }


    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 l’aide d’une r´ f´ rence qui part de la premi` re cellule de la liste et suit l’en-
                      e e`                   ee                             e
    chaˆnement des cellules.
        ı
´                          ˆ ´
    14.3. OPERATIONS SUR LES LISTES CHAINEES                                                                     5

        La figure 14.2 illustre le principe du parcours it´ ratif d’une liste a l’aide d’une r´ f´ rence ref.
                                                         e                   `               ee

                                  ref        ........          ref
                      liste
                                        e1           ...             ei          ...           en

                         F IG . 14.2 – Parcours it´ ratif d’une liste a l’aide d’une r´ f´ rence
                                                  e                   `               ee


    Calculer la longueur d’une 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   public int longueur (){
2     i n t compteur = 0 ;
3     Liste ref=this ;
4     while ( r e f != n u l l ){
5         c o m p t e u r ++;
6         ref=ref . reste ();     / / ou r e f = r e f . s u i v a n t
7     }
8     return compteur ;
9   }


    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 qu’elle devient nulle a la fin de la liste. Chaque fois qu’elle pointe vers une nouvelle
               a                         `
        cellule, le compteur est incr´ ment´ . Remarquez que l’avancement dans la liste se fait en utili-
                                      e     e
        sant la m´ thode reste de la cellule courante, ou sinon l’acc` s direct a la variable d’instance
                  e                                                      e         `
        suivant.

                                 ´e       `
    V´ rifier l’appartenance d’un 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 s’arrˆ te a ce moment-l` , sinon il
               ee                            ee                 e                    e `               a
    continue jusqu’` la fin de la liste.
                     a

                                         Listing 14.7 – (lien vers le code brut)
1   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 ) {
2      Liste ref=this ;
3      while ( r e f != n u l l ){
4           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
5               return true ;                              / / l ’ element a ete retrouve
6           else ref=ref . reste ();                       / / ou r e f = r e f . s u i v a n t
7      }
8      return f a l s e ;                                  / / l ’ element n ’ a pas e t e r e t r o u v e
9   }
6                                                                                                  ˆ ´
                                                                                CHAPITRE 14. LISTES CHAINEES

    Remarque : L’arrˆ t du parcours en cas de succ` s se fait en retournant directement true pendant
                      e                                 e
        l’ex´ 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 l’acc` s direct a la variable d’instance element.
                        e        `

    Concat´ nation de deux listes
          e
        Cette op´ ration, r´ alis´ e par la m´ thode concatenation, rajoute a la fin 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 cou-
                                         e           e           e
    rante, afin 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´ modifi´ e, en lui rajoutant par concat´ nation une autre liste.
                                            ´e       e                               e

                                       Listing 14.8 – (lien vers le code brut)
1   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 ){
2     Liste ref=this ;
3     while ( r e f . r e s t e ( ) != n u l l ){         / / ou r e f . s u i v a n t != n u l l
4         ref=ref . reste ();                             / / ou r e f = r e f . s u i v a n t
5     }
6     / / re f pointe maintenant sur la                   d e r n i e r e c e l l u l e de l a l i s t e
7     ref . modifieReste ( l i s t e ) ;                / / ou r e f . s u i v a n t= l i s t e
8   }

    Remarque : La condition de la boucle while change ici, car on veut s’arrˆ ter sur la derni` re cellule et
                                                                            e                 e
        non pas la d´ passer comme dans les m´ thodes pr´ c´ dentes. Remarquez que l’enchaˆnement des
                    e                          e          e e                                  ı
        deux listes se fait en modifiant la variable d’instance suivant de la derni` re cellule a l’aide
                                                                                        e           `
        de la m´ thode modifieReste, ou sinon par modification directe de celle-ci.
               e

                                                ´e
    Suppression de la premi` re occurrence d’un 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 (s’il 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 d’une cellule de la liste se fait de la mani` re suivante (voir la figure 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 mo-
                                      e e                 ´
           difiant la variable suivant du pr´ d´ cesseur pour qu’elle pointe vers la mˆ me chose que la
                                                   e e                                        e
           variable suivant de la cellule.
        pred     ref                                                                     pred         ref
                                                  liste
        liste
                       e         e2         ...                        e1         ...           ei          e   ...

        nouvelle liste

                                 F IG . 14.3 – Suppression d’une cellule de la liste
´                          ˆ ´
     14.3. OPERATIONS SUR LES LISTES CHAINEES                                                                                              7

         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
     s’arrˆ te sur la cellule qui contient l’´ l´ ment, la suppression n’est plus possible, car on n’a plus acc` s
          e                                  ee                                                                e
     au pr´ d´ cesseur (dans les listes chaˆn´ 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   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 ) {
 2      Liste ref=this ;                     / / r e f e r e n c e qui cherche elem
 3      L i s t e pred= null ;               / / predecesseur , i n i t i a l i s e a nu l l
 4      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
 5          pred = r e f ;                           / / avance pred
 6           ref = ref . reste ();                   / / avance r e f
 7      }
 8      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
 9           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
10               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
11           else {                                         / / m i l i e u de l a l i s t e
12               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
13               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
14          }
15      }
16      e l s e return t h i s ;                            / / e l e m e n t non t r o u v e
17   }


     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 figure 14.4). Le cas le plus simple (condition d’arrˆ t) est la liste avec une
                                                                                      e
     seule cellule.

                                                                      premier reste
                                                      liste
                                                                        e             ...

                                        F IG . 14.4 – D´ composition r´ cursive d’une liste
                                                       e              e


     Calcul r´ cursif de la longueur d’une 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                                                                                                         ˆ ´
                                                                                       CHAPITRE 14. LISTES CHAINEES

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



     e            e                           `
    V´ rification r´ cursive de l’appartenance a une liste

         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 d’arrˆ t : quand on trouve l’´ l´ ment recherch´ ou
                                                                  e                   ee                e
    quand la liste n’a 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   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 ) {
2      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
3      Liste resteListe = reste () ;                                   / / ou r e s t e L i s t e = s u i v a n t ;
4      i f ( r e s t e L i s t e == n u l l )                          / / condition d ’ arret
5          return f a l s e ;
6      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 ) ;
7   }



    Concat´ nation r´ cursive de deux listes
          e         e

         L’action 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 modifier la
    r´ f´ rence vers la cellule suivante pour enchaˆner la liste param` tre. Sinon, il suffit de concat´ ner le
     ee                                             ı                  e                              e
    reste avec la liste param` tre.
                               e

                                             Listing 14.12 – (lien vers le code brut)
1   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 ){
2     Liste resteListe = reste () ;                  / / ou r e s t e L i s t e = s u i v a n t ;
3     i f ( r e s t e L i s t e == n u l l )         / / condition d ’ arret
4         modifieReste ( l i s t e ) ;               / / ou s u i v a n t= l i s t e
5     else resteListe . concatenation ( l i s t e );
6   }
´                          ˆ ´
     14.3. OPERATIONS SUR LES LISTES CHAINEES                                                                                            9

                  e                    e                    ´e
     Suppression r´ cursive de la premi` re occurrence d’un el´ ment

          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 n’a 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    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 ) {
2       Liste resteListe = reste () ;                          / / ou r e s t e L i s t e = s u i v a n t ;
3       i f ( elem == p r e m i e r ( ) )                      / / ou e l e m==e l e m e n t
4           return r e s t e L i s t e ;
5       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 ) ;
6       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 ) ) ;
7    }


     Remarque : L’inconv´ nient de cette m´ thode est qu’on cr´ e des copies de toutes les cellules qui ne
                          e                 e                     e
         contiennent pas l’´ l´ ment recherch´ . Pour eviter cela, la d´ finition 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 l’action reste=reste.suppressionPremier(e)
                           e
                          si premier!=e et reste!=null


                                                 Listing 14.14 – (lien vers le code brut)
 1   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 ) {
 2      Liste resteListe = reste () ;                              / / ou r e s t e L i s t e = s u i v a n t ;
 3      i f ( elem == p r e m i e r ( ) )                          / / ou e l e m==e l e m e n t
 4          return r e s t e L i s t e ;
 5      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 ;
 6      else {
 7           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 ) ) ;
 8          return t h i s ;
 9      }
10   }
10                                                                                                         ˆ ´
                                                                                         CHAPITRE 14. LISTES CHAINEES

     14.4 Listes tri´ es
                    e
         Nous nous int´ ressons maintenant aux listes chaˆn´ es dans lesquelles les el´ ments respectent un
                         e                                    ı e                         ´e
     ordre croissant. Dans ce cas, les m´ thodes de recherche, d’insertion et de suppression sont diff´ rentes.
                                          e                                                                e
     L’ordre des el´ ments permet d’arrˆ ter plus tˆ t la recherche d’un el´ ment qui n’existe pas dans la liste.
                  ´e                     e          o                      ´e
     Aussi, l’insertion ne se fait plus en d´ but de liste, mais a la place qui pr´ serve l’ordre des el´ ments.
                                            e                    `                e                   ´e
         Nous utiliserons une classe ListeTriee qui est tr` s similaire a la classe Liste, mais dans la-
                                                                   e           `
     quelle on s’int´ resse uniquement aux m´ thodes de recherche (contientTriee), d’insertion (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   class ListeTriee {
 2     int element ;
 3     ListeTriee suivant ;
 4
 5        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 ){
 6          element = premier ;
 7          suivant = reste ;
 8        }
 9
10        public      int premier ( ) { . . . }
11        public      ListeTriee reste ( ) { . . . }
12        public      v o i d m o d i f i e P r e m i e r ( i n t elem ) { . . . }
13        public      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 ) { . . . }
14
15        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 ) { . . . }
16        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 ) { . . . }
17        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 ) { . . . }
18   }



     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
     s’arrˆ 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    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 ) {
2       ListeTriee ref=this ;
3       w h i l e ( r e f ! = n u l l && r e f . p r e m i e r ( ) <= elem ) {
4            i f ( r e f . p r e m i e r ( ) == elem )
5                return true ;
6            else ref=ref . reste ();
7       }
8       return f a l s e ;
9    }
´
    14.4. LISTES TRIEES                                                                                                11

    Variante r´ cursive :
              e

                                             Listing 14.17 – (lien vers le code brut)
1   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 ) {
2      i f ( elem == p r e m i e r ( ) ) r e t u r n t r u e ;
3      i f ( elem < p r e m i e r ( ) ) r e t u r n f a l s e ;
4      ListeTriee resteListe = reste () ;
5      i f ( r e s t e L i s t e == n u l l )
6          return f a l s e ;
7      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 ) ;
8   }


    14.4.2 Insertion dans une liste tri´ e
                                       e
        L’insertion d’un 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 figure 14.5 montre les deux cas d’insertion :
        – en d´ but de liste.
                e
          Elle est similaire alors a l’op´ ration insertionDebut de la classe Liste
                                   `     e
        – en milieu de liste.
          La recheche de la position d’insertion se fait alors avec une m´ thode similaire a celle uti-
                                                                             e                  `
          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 modifi´ pour pointer vers la nouvelle cellule, tandis que celle-ci doit
                  e e            ˆ            e
          pointer vers la cellule courante (ref).

                    pred         ref                                                          pred        ref
                                                              liste
                  liste
      nouvelle liste                   e1          ...                        e1        ...          ep         er   ...
                         e
                                                                                                          e

                                            F IG . 14.5 – Insertion dans une liste tri´ e
                                                                                      e

          Dans la figure 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, l’insertion se fait a
      ee        `    e                                     ´e                                                    `
    la fin de la liste, donc au moment de l’arrˆ 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 figure 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   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 ) {
2      ListeTriee ref=this ;                       / / r e f e r e n c e qui cherche elem
3      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
4      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
5          pred = r e f ;                        / / avance pred
6           ref = ref . reste ();                / / avance r e f
12                                                                                                             ˆ ´
                                                                                             CHAPITRE 14. LISTES CHAINEES

 7        }
 8        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
 9            r e t u r n new L i s t e T r i e e ( elem , t h i s ) ;
10        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
11            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 ) ;
12            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
13            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
14        }
15   }


     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). L’insertion 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, l’insertion se fera en tˆ te de liste. Sinon,
               ee       `     e                      ´     `                                   e
     l’insertion 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 n’est pas vide, l’insertion se fait r´ cursivement dans reste et le r´ sultat
              `     e                                                      e                                 e
     remplace l’ancien reste.

                                                 Listing 14.19 – (lien vers le code brut)
 1   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 ) {
 2      i f ( elem <= p r e m i e r ( ) )
 3          r e t u r n new L i s t e T r i e e ( elem , t h i s ) ;
 4      else {
 5           ListeTriee resteListe = reste ();
 6           i f ( r e s t e L i s t e == n u l l )
 7               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 ) ) ;
 8           else
 9               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 ) ) ;
10          return t h i s ;
11      }
12   }



     14.4.3 Suppression dans une liste tri´ e
                                          e
         La suppression de la premi` re occurrence d’un 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´ ficie du tri des valeurs. Aussi, si plusieurs occurrences de l’´ l´ ment existent, elles
                      e e                                                                 ee
     sont forc´ ment l’une a la suite de l’autre 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 qu’il faut v´ rifier que ref pointe vraiment la valeur
                              ee                 e                       e
     recherch´ e.
               e

                                             Listing 14.20 – (lien vers le code brut)
 1   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 ) {
 2      Liste ref=this ;                     / / r e f e r e n c e qui cherche elem
 3      L i s t e pred= null ;               / / predecesseur , i n i t i a l i s e a nu l l
 4      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
 5          pred = r e f ;                           / / avance pred
 6           ref = ref . reste ();                   / / avance r e f
 7      }
 8      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
 9           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
10               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
11           else {                                         / / m i l i e u de l a l i s t e
12               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
13               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
14          }
15      }
16      e l s e return t h i s ;                            / / e l e m e n t non t r o u v e
17   }


     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 d’arrˆ t est rajout´ e :
                                    e           e
     quand l’´ l´ ment a eliminer est plus petit que premier, il n’existe sˆ rement pas dans la liste et celle-ci
               ee       `´                                                 u
     est retourn´ e non modifi´ e.
                 e              e

                                             Listing 14.21 – (lien vers le code brut)
 1   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 ) {
 2      Liste resteListe = reste () ;
 3      i f ( elem == p r e m i e r ( ) )
 4          return r e s t e L i s t e ;
 5      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
 6      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 ;
 7      else {
 8           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 ) ) ;
 9          return t h i s ;
10      }
11   }




     14.5 Un exemple de programme qui utilise les listes
         Consid´ rons un exemple simple de programme qui manipule des listes chaˆn´ 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 final). La liste doit garder les el´ ments dans l’ordre dans lequel ils sont introduits.
                                                            ´e
     Egalement, une valeur ne doit etre stock´ e qu’une 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 l’ordre des el´ ments. Les el´ ments de cette seconde liste
                                                                   ´e             ´e
     devront etre elimin´ s de la liste initiale.
              ˆ ´         e
          A la fin, le programme affiche ce qui reste de la premi` re liste.
                                                                     e
     Remarque : Pour garder les el´ ments dans l’ordre d’introduction, l’insertion d’un nouvel el´ ment
                                   ´e                                                          ´e
         doit se faire en fin de liste. La m´ thode insertionDebut ne convient donc pas. La solution
                                           e
         est d’utiliser la m´ thode concatenation.
                            e
     Remarque : Pour qu’un el´ ment soit stock´ une seule fois dans la liste, il faut d’abord v´ rifier s’il
                                 ´e                e                                           e
         n’y est pas d´ j` , a l’aide 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   public cl as s ExempleListes{
 2     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 ) {
 3        / / 1. Creation premiere l i s t e
 4        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 : ” ) ;
 5        Liste l i s t e = null ;                    / / l i s t e a construire
 6        do {
 7             i nt val = Terminal . l i r e I n t ( ) ;
 8             i f ( v a l ==0) break ;
 9             i f ( l i s t e == n u l l )
10                 l i s t e = new L i s t e ( v a l , n u l l ) ;
11             else i f (! l i s t e . contient ( val ))
12                 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 ) ) ;
13        } while ( true ) ;
14
15         / / 2. Creation seconde l i s t e
16         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 ) : ” ) ;
17         Liste l i s t e 2 = null ;
18         do {
19             i nt val = Terminal . l i r e I n t ( ) ;
20             i f ( v a l ==0) break ;
21             i f ( l i s t e 2 == n u l l )
22                 l i s t e 2 = new L i s t e ( v a l , n u l l ) ;
23             else l i s t e 2 = l i s t e 2 . insertionDebut ( val ) ;
24         } while ( true ) ;
25
26         / / 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
27         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 ( ) ) {
28             i f ( l i s t e == n u l l ) break ;    / / plus rien a eliminer
29             l i s t e = l i s t e . suppressionPremier ( r ef . premier ( ) ) ;
30         }
31
32         / / 4. Affichage l i s t e restante
33         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 : ” ) ;
34         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 ( ) )
35             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   15

36           Terminal . sautDeLigne ( ) ;
37       }
38   }

Weitere ähnliche Inhalte

Was ist angesagt?

Chapitre 1 arbres de recherche
Chapitre 1 arbres de rechercheChapitre 1 arbres de recherche
Chapitre 1 arbres de rechercheSana Aroussi
 
Red black tree
Red black treeRed black tree
Red black treeRajendran
 
Discover Tasty Query: The library for Scala program analysis
Discover Tasty Query: The library for Scala program analysisDiscover Tasty Query: The library for Scala program analysis
Discover Tasty Query: The library for Scala program analysisJames Thompson
 
Cours : les listes chainées Prof. KHALIFA MANSOURI
Cours : les listes chainées  Prof. KHALIFA MANSOURI Cours : les listes chainées  Prof. KHALIFA MANSOURI
Cours : les listes chainées Prof. KHALIFA MANSOURI Mansouri Khalifa
 
Trees - Non Linear Data Structure
Trees - Non Linear Data StructureTrees - Non Linear Data Structure
Trees - Non Linear Data StructurePriyanka Rana
 
Unit 3 graph chapter6
Unit 3  graph chapter6Unit 3  graph chapter6
Unit 3 graph chapter6DrkhanchanaR
 
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI Mansouri Khalifa
 
Chapitre 8: Les arbres
Chapitre 8: Les  arbresChapitre 8: Les  arbres
Chapitre 8: Les arbresMohamed Lahby
 
Chapitre 3 structures séquentielles
Chapitre 3 structures séquentiellesChapitre 3 structures séquentielles
Chapitre 3 structures séquentiellesSana Aroussi
 
Unit 3 Tree chapter 5
Unit 3  Tree chapter 5Unit 3  Tree chapter 5
Unit 3 Tree chapter 5DrkhanchanaR
 
Functional dependency and normalization
Functional dependency and normalizationFunctional dependency and normalization
Functional dependency and normalizationUniversity of Potsdam
 
non linear data structure -introduction of tree
non linear data structure -introduction of treenon linear data structure -introduction of tree
non linear data structure -introduction of treeSiddhi Viradiya
 

Was ist angesagt? (20)

Chapitre 1 rappel
Chapitre 1 rappelChapitre 1 rappel
Chapitre 1 rappel
 
Chapitre 1 arbres de recherche
Chapitre 1 arbres de rechercheChapitre 1 arbres de recherche
Chapitre 1 arbres de recherche
 
Red black tree
Red black treeRed black tree
Red black tree
 
Discover Tasty Query: The library for Scala program analysis
Discover Tasty Query: The library for Scala program analysisDiscover Tasty Query: The library for Scala program analysis
Discover Tasty Query: The library for Scala program analysis
 
Cours : les listes chainées Prof. KHALIFA MANSOURI
Cours : les listes chainées  Prof. KHALIFA MANSOURI Cours : les listes chainées  Prof. KHALIFA MANSOURI
Cours : les listes chainées Prof. KHALIFA MANSOURI
 
Trees - Non Linear Data Structure
Trees - Non Linear Data StructureTrees - Non Linear Data Structure
Trees - Non Linear Data Structure
 
B+ trees and height balance tree
B+ trees and height balance treeB+ trees and height balance tree
B+ trees and height balance tree
 
Unit 3 graph chapter6
Unit 3  graph chapter6Unit 3  graph chapter6
Unit 3 graph chapter6
 
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
 
Chapitre 1 rappel
Chapitre 1   rappelChapitre 1   rappel
Chapitre 1 rappel
 
Avl trees
Avl treesAvl trees
Avl trees
 
Binary tree
Binary tree Binary tree
Binary tree
 
PRIM'S ALGORITHM
PRIM'S ALGORITHMPRIM'S ALGORITHM
PRIM'S ALGORITHM
 
Data Structure (Tree)
Data Structure (Tree)Data Structure (Tree)
Data Structure (Tree)
 
Chapitre 8: Les arbres
Chapitre 8: Les  arbresChapitre 8: Les  arbres
Chapitre 8: Les arbres
 
Chapitre 3 structures séquentielles
Chapitre 3 structures séquentiellesChapitre 3 structures séquentielles
Chapitre 3 structures séquentielles
 
Unit 3 Tree chapter 5
Unit 3  Tree chapter 5Unit 3  Tree chapter 5
Unit 3 Tree chapter 5
 
Lec7
Lec7Lec7
Lec7
 
Functional dependency and normalization
Functional dependency and normalizationFunctional dependency and normalization
Functional dependency and normalization
 
non linear data structure -introduction of tree
non linear data structure -introduction of treenon linear data structure -introduction of tree
non linear data structure -introduction of tree
 

Andere mochten auch

Chap listes
Chap listesChap listes
Chap listessunsaida
 
Corrigé langage c
Corrigé langage cCorrigé langage c
Corrigé langage ccoursuniv
 
Chapitre 1 arbres de recherche
Chapitre 1 arbres de rechercheChapitre 1 arbres de recherche
Chapitre 1 arbres de rechercheSana Aroussi
 
La complexité des algorithmes récursives Géométrie algorithmique
La complexité des algorithmes récursivesGéométrie algorithmiqueLa complexité des algorithmes récursivesGéométrie algorithmique
La complexité des algorithmes récursives Géométrie algorithmiqueHajer Trabelsi
 
Le problème de voyageur de commerce: algorithme génétique
Le problème de voyageur de commerce: algorithme génétiqueLe problème de voyageur de commerce: algorithme génétique
Le problème de voyageur de commerce: algorithme génétiqueRima Lassoued
 
Chapitre 4 heuristiques et méta heuristiques
Chapitre 4 heuristiques et méta heuristiquesChapitre 4 heuristiques et méta heuristiques
Chapitre 4 heuristiques et méta heuristiquesSana Aroussi
 
Chapitre 2 problème de plus court chemin
Chapitre 2 problème de plus court cheminChapitre 2 problème de plus court chemin
Chapitre 2 problème de plus court cheminSana Aroussi
 
Cours structures des données (langage c)
Cours structures des données (langage c)Cours structures des données (langage c)
Cours structures des données (langage c)rezgui mohamed
 
Présentation pi batimat v2
Présentation pi batimat v2Présentation pi batimat v2
Présentation pi batimat v2Olivier Allardi
 
Mariage_M.Alain
Mariage_M.AlainMariage_M.Alain
Mariage_M.Alainsarabilali
 
Enquete de satisfaction ste marie
Enquete de satisfaction ste marieEnquete de satisfaction ste marie
Enquete de satisfaction ste mariepptenligne
 
Presentación sobre la situación del Social Media por Emilio Márquez Espino
Presentación sobre la situación del Social Media por Emilio Márquez EspinoPresentación sobre la situación del Social Media por Emilio Márquez Espino
Presentación sobre la situación del Social Media por Emilio Márquez EspinoEmilio Márquez Espino
 
Mv 34-pct-e.rev0.23.03.04
Mv 34-pct-e.rev0.23.03.04Mv 34-pct-e.rev0.23.03.04
Mv 34-pct-e.rev0.23.03.04AMITS
 
Un hold up comme si l’on y était
Un hold up comme si l’on y étaitUn hold up comme si l’on y était
Un hold up comme si l’on y étaitShirley Maenhoudt
 

Andere mochten auch (20)

Chap listes
Chap listesChap listes
Chap listes
 
Corrigé langage c
Corrigé langage cCorrigé langage c
Corrigé langage c
 
Corrections td4
Corrections td4Corrections td4
Corrections td4
 
Chapitre 1 arbres de recherche
Chapitre 1 arbres de rechercheChapitre 1 arbres de recherche
Chapitre 1 arbres de recherche
 
La complexité des algorithmes récursives Géométrie algorithmique
La complexité des algorithmes récursivesGéométrie algorithmiqueLa complexité des algorithmes récursivesGéométrie algorithmique
La complexité des algorithmes récursives Géométrie algorithmique
 
Algorithm et structure de donnée
Algorithm et structure de donnéeAlgorithm et structure de donnée
Algorithm et structure de donnée
 
Le problème de voyageur de commerce: algorithme génétique
Le problème de voyageur de commerce: algorithme génétiqueLe problème de voyageur de commerce: algorithme génétique
Le problème de voyageur de commerce: algorithme génétique
 
Chapitre 4 heuristiques et méta heuristiques
Chapitre 4 heuristiques et méta heuristiquesChapitre 4 heuristiques et méta heuristiques
Chapitre 4 heuristiques et méta heuristiques
 
Chapitre 2 problème de plus court chemin
Chapitre 2 problème de plus court cheminChapitre 2 problème de plus court chemin
Chapitre 2 problème de plus court chemin
 
Cours structures des données (langage c)
Cours structures des données (langage c)Cours structures des données (langage c)
Cours structures des données (langage c)
 
Innovacion
InnovacionInnovacion
Innovacion
 
Présentation pi batimat v2
Présentation pi batimat v2Présentation pi batimat v2
Présentation pi batimat v2
 
`Davos Y Cc
`Davos Y Cc`Davos Y Cc
`Davos Y Cc
 
Mariage_M.Alain
Mariage_M.AlainMariage_M.Alain
Mariage_M.Alain
 
Coupures de Presse
Coupures de PresseCoupures de Presse
Coupures de Presse
 
CRG-25eme-2014
CRG-25eme-2014CRG-25eme-2014
CRG-25eme-2014
 
Enquete de satisfaction ste marie
Enquete de satisfaction ste marieEnquete de satisfaction ste marie
Enquete de satisfaction ste marie
 
Presentación sobre la situación del Social Media por Emilio Márquez Espino
Presentación sobre la situación del Social Media por Emilio Márquez EspinoPresentación sobre la situación del Social Media por Emilio Márquez Espino
Presentación sobre la situación del Social Media por Emilio Márquez Espino
 
Mv 34-pct-e.rev0.23.03.04
Mv 34-pct-e.rev0.23.03.04Mv 34-pct-e.rev0.23.03.04
Mv 34-pct-e.rev0.23.03.04
 
Un hold up comme si l’on y était
Un hold up comme si l’on y étaitUn hold up comme si l’on y était
Un hold up comme si l’on y était
 

listes chainée en JAVA

  • 1. Chapitre 14 Listes chaˆn´ es ı e 14.1 La notion de liste Une liste est une structure de donn´ es qui permet de stocker une s´ quence d’objets d’un mˆ me e e e type. En cela, les listes ressemblent aux tableaux. La s´ quence d’entiers 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 n’importe quel el´ ment par son indice (acc` s dit al´ atoire), e e ` ´e e e tandis que dans une liste chaˆn´ e on a acc` s aux el´ ments un apr` s l’autre, a partir du premier ı e e ´e e ` el´ ment (acc` s dit s´ quentiel). ´e e e – Un tableau a une taille fixe, tandis qu’une liste peut augmenter en taille ind´ finiment (on peut e toujours rajouter un el´ ment a une liste). ´e ` D´ finition (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´ finition r´ cursive aux listes chaˆn´ 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´ finition est r´ cursive, car une liste est d´ finie en fonction d’une autre liste. Une telle e e e d´ finition r´ cursive est correcte, car une liste est d´ finie en fonction d’une liste plus courte, qui contient e e e un el´ ment de moins. Cette d´ finition permet de construire n’importe quelle liste en partant de la liste ´e e vide. Conclusion : la liste chaˆn´ e est une structure de donn´ es r´ cursive. ı e e e La validit´ de cette d´ finition r´ cursive peut etre discut´ e d’un 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´ finition donne une d´ composition r´ cursive des listes. La condition g´ n´ rale d’arrˆ 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 d’une unit´ . Cela garantit que la d´ composition m` ne toujours a une liste de ` e e e ` longueur 0, la liste vide (condition d’arrˆ t). e 1
  • 2. 2 ˆ ´ CHAPITRE 14. LISTES CHAINEES 14.2 Repr´ sentation des listes chaˆn´ es en Java e ı e Il y a plusieurs facons de repr´ senter les listes chaˆn´ es en Java. L’id´ e de base est d’utiliser un ¸ e ı e e enchaˆnement 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 enchaˆnement. ı La figure 14.1 illustre cette repr´ sentation pour la liste exemple ci-dessus [3, 7, 2, 4]. e liste 3 7 2 4 F IG . 14.1 – Repr´ sentation par enchaˆnement de cellules de la liste [3, 7, 2, 4] e ı En Java, les r´ f´ rences ne sont pas d´ finies 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 d’instance. e e ee e Comme une liste est d´ finie 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´ finit une liste e e e d’entiers. Listing 14.1 – (lien vers le code brut) 1 class Liste { 2 int element ; 3 Liste suivant ; 4 5 L i s t e ( i nt premier , L i s t e r e s t e ){ 6 element = premier ; 7 suivant = reste ; 8 } 9 } 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 l’inconv´ nient de ne repr´ senter que des listes avec au moins une cel- e e lule. La liste vide, qui selon la d´ finition 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 l’avantage de la simplicit´ et nous l’utiliserons dans e e le reste de ce cours. 14.3 Op´ rations sur les listes chaˆn´ es e ı e Nous etudierons les op´ rations les plus importantes sur les listes chaˆn´ 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 l’action de vider une liste ne peuvent pas etre des m´ thodes de la ˆ e
  • 3. ´ ˆ ´ 14.3. OPERATIONS SUR LES LISTES CHAINEES 3 classe Liste. Ces op´ rations doivent etre effectu´ es a l’ext´ rieur de la classe Liste, par le e ˆ e ` e programme qui utilise les listes. Conform´ ment a leur d´ finition, les listes sont des structures r´ cursives. Par cons´ quent, les e ` e e e op´ rations sur les listes s’expriment 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 class Liste { 2 int element ; 3 Liste suivant ; 4 5 public L i s t e ( i nt premier , L i s t e r e s t e ){ 6 element = premier ; 7 suivant = reste ; 8 } 9 10 public int premier ( ) { . . . } 11 public Liste reste ( ) { . . . } 12 public v o i d m o d i f i e P r e m i e r ( i n t elem ) { . . . } 13 public void m o d i f i e R e s t e ( L i s t e r e s t e ) { . . . } 14 public int longueur ( ) { . . . } 15 public b o o l e a n c o n t i e n t ( i n t elem ) { . . . } 16 public L i s t e i n s e r t i o n D e b u t ( i n t elem ) { . . . } 17 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 ) { . . . } 18 public 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 ) { . . . } 19 } 14.3.1 Op´ rations sans parcours de liste e Pour ces op´ rations il n’y a pas de variantes it´ ratives et r´ cursives, l’action est r´ alis´ e directe- e 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 d’instance element et suivant. e Nous verrons plus tard que l’acc` s direct aux variables d’instance est d´ conseill´ dans la program- e e e mation orient´ e-objet. A la place, on pr´ ferre “cacher” les variables d’instance et donner acc` s a leur e e e ` valeurs a travers des m´ thodes. Ceci fera l’objet d’un prochain cours. ` e Aussi, ces m´ thodes correspondent aux el´ ments de la d´ composition r´ cursive d’une liste et sont e ´e e e bien adapt´ es a l’´ criture d’algorithmes r´ cursifs sur les listes. e ` e e Listing 14.3 – (lien vers le code brut) 1 public int premier (){
  • 4. 4 ˆ ´ CHAPITRE 14. LISTES CHAINEES 2 return element ; 3 } 4 5 public Liste r e s t e (){ 6 return s u i v a n t ; 7 } 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 signifie 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 Modifier le premier el´ ment et le reste de la liste Ces op´ rations sont r´ alis´ es par les m´ thodes modifiePremier (qui modifie le premier el´ ment e e e e ´e de la liste), respectivement modifieReste (qui modifie le reste de la liste). Ces m´ thodes permettent donc de modifier 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 l’acc` s direct aux variables d’instance par des appels de m´ thodes. e e Listing 14.4 – (lien vers le code brut) 1 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 ) { 2 e l e m e n t = elem ; 3 } 4 5 public void m o d i f i e R e s t e ( L i s t e r e s t e ){ 6 suivant = reste ; 7 } e ´e Ins´ rer un el´ ment en tˆ te de liste e L’insertion en tˆ te de liste est r´ alis´ e par la m´ thode insertionDebut. C’est 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 enchaˆne l’ancienne liste. ı La m´ thode insertionDebut retourne une nouvelle liste, car la liste initiale est modifi´ e par e e l’insertion (la premi` re cellule de la nouvelle liste est diff´ rente). e e Listing 14.5 – (lien vers le code brut) 1 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 ) { 2 r e t u r n new L i s t e ( elem , t h i s ) ; 3 } 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 l’aide d’une r´ f´ rence qui part de la premi` re cellule de la liste et suit l’en- e e` ee e chaˆnement des cellules. ı
  • 5. ´ ˆ ´ 14.3. OPERATIONS SUR LES LISTES CHAINEES 5 La figure 14.2 illustre le principe du parcours it´ ratif d’une liste a l’aide d’une r´ f´ rence ref. e ` ee ref ........ ref liste e1 ... ei ... en F IG . 14.2 – Parcours it´ ratif d’une liste a l’aide d’une r´ f´ rence e ` ee Calculer la longueur d’une 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 public int longueur (){ 2 i n t compteur = 0 ; 3 Liste ref=this ; 4 while ( r e f != n u l l ){ 5 c o m p t e u r ++; 6 ref=ref . reste (); / / ou r e f = r e f . s u i v a n t 7 } 8 return compteur ; 9 } 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 qu’elle devient nulle a la fin de la liste. Chaque fois qu’elle pointe vers une nouvelle a ` cellule, le compteur est incr´ ment´ . Remarquez que l’avancement dans la liste se fait en utili- e e sant la m´ thode reste de la cellule courante, ou sinon l’acc` s direct a la variable d’instance e e ` suivant. ´e ` V´ rifier l’appartenance d’un 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 s’arrˆ te a ce moment-l` , sinon il ee ee e e ` a continue jusqu’` la fin de la liste. a Listing 14.7 – (lien vers le code brut) 1 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 ) { 2 Liste ref=this ; 3 while ( r e f != n u l l ){ 4 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 5 return true ; / / l ’ element a ete retrouve 6 else ref=ref . reste (); / / ou r e f = r e f . s u i v a n t 7 } 8 return f a l s e ; / / l ’ element n ’ a pas e t e r e t r o u v e 9 }
  • 6. 6 ˆ ´ CHAPITRE 14. LISTES CHAINEES Remarque : L’arrˆ t du parcours en cas de succ` s se fait en retournant directement true pendant e e l’ex´ 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 l’acc` s direct a la variable d’instance element. e ` Concat´ nation de deux listes e Cette op´ ration, r´ alis´ e par la m´ thode concatenation, rajoute a la fin 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 cou- e e e rante, afin 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´ modifi´ e, en lui rajoutant par concat´ nation une autre liste. ´e e e Listing 14.8 – (lien vers le code brut) 1 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 ){ 2 Liste ref=this ; 3 while ( r e f . r e s t e ( ) != n u l l ){ / / ou r e f . s u i v a n t != n u l l 4 ref=ref . reste (); / / ou r e f = r e f . s u i v a n t 5 } 6 / / re f pointe maintenant sur la d e r n i e r e c e l l u l e de l a l i s t e 7 ref . modifieReste ( l i s t e ) ; / / ou r e f . s u i v a n t= l i s t e 8 } Remarque : La condition de la boucle while change ici, car on veut s’arrˆ ter sur la derni` re cellule et e e non pas la d´ passer comme dans les m´ thodes pr´ c´ dentes. Remarquez que l’enchaˆnement des e e e e ı deux listes se fait en modifiant la variable d’instance suivant de la derni` re cellule a l’aide e ` de la m´ thode modifieReste, ou sinon par modification directe de celle-ci. e ´e Suppression de la premi` re occurrence d’un 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 (s’il 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 d’une cellule de la liste se fait de la mani` re suivante (voir la figure 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 mo- e e ´ difiant la variable suivant du pr´ d´ cesseur pour qu’elle pointe vers la mˆ me chose que la e e e variable suivant de la cellule. pred ref pred ref liste liste e e2 ... e1 ... ei e ... nouvelle liste F IG . 14.3 – Suppression d’une cellule de la liste
  • 7. ´ ˆ ´ 14.3. OPERATIONS SUR LES LISTES CHAINEES 7 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 s’arrˆ te sur la cellule qui contient l’´ l´ ment, la suppression n’est plus possible, car on n’a plus acc` s e ee e au pr´ d´ cesseur (dans les listes chaˆn´ 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 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 ) { 2 Liste ref=this ; / / r e f e r e n c e qui cherche elem 3 L i s t e pred= null ; / / predecesseur , i n i t i a l i s e a nu l l 4 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 5 pred = r e f ; / / avance pred 6 ref = ref . reste (); / / avance r e f 7 } 8 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 9 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 10 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 11 else { / / m i l i e u de l a l i s t e 12 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 13 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 14 } 15 } 16 e l s e return t h i s ; / / e l e m e n t non t r o u v e 17 } 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 figure 14.4). Le cas le plus simple (condition d’arrˆ t) est la liste avec une e seule cellule. premier reste liste e ... F IG . 14.4 – D´ composition r´ cursive d’une liste e e Calcul r´ cursif de la longueur d’une 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. 8 ˆ ´ CHAPITRE 14. LISTES CHAINEES 2 Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; 3 i f ( r e s t e L i s t e == n u l l ) / / condition d ’ arret 4 return 1; 5 e l s e return 1 + r e s t e L i s t e . longueur ( ) ; 6 } e e ` V´ rification r´ cursive de l’appartenance a une liste 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 d’arrˆ t : quand on trouve l’´ l´ ment recherch´ ou e ee e quand la liste n’a 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 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 ) { 2 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 3 Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; 4 i f ( r e s t e L i s t e == n u l l ) / / condition d ’ arret 5 return f a l s e ; 6 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 ) ; 7 } Concat´ nation r´ cursive de deux listes e e L’action 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 modifier la r´ f´ rence vers la cellule suivante pour enchaˆner la liste param` tre. Sinon, il suffit de concat´ ner le ee ı e e reste avec la liste param` tre. e Listing 14.12 – (lien vers le code brut) 1 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 ){ 2 Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; 3 i f ( r e s t e L i s t e == n u l l ) / / condition d ’ arret 4 modifieReste ( l i s t e ) ; / / ou s u i v a n t= l i s t e 5 else resteListe . concatenation ( l i s t e ); 6 }
  • 9. ´ ˆ ´ 14.3. OPERATIONS SUR LES LISTES CHAINEES 9 e e ´e Suppression r´ cursive de la premi` re occurrence d’un el´ ment 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 n’a 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 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 ) { 2 Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; 3 i f ( elem == p r e m i e r ( ) ) / / ou e l e m==e l e m e n t 4 return r e s t e L i s t e ; 5 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 ) ; 6 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 ) ) ; 7 } Remarque : L’inconv´ nient de cette m´ thode est qu’on cr´ e des copies de toutes les cellules qui ne e e e contiennent pas l’´ l´ ment recherch´ . Pour eviter cela, la d´ finition 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 l’action reste=reste.suppressionPremier(e) e si premier!=e et reste!=null Listing 14.14 – (lien vers le code brut) 1 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 ) { 2 Liste resteListe = reste () ; / / ou r e s t e L i s t e = s u i v a n t ; 3 i f ( elem == p r e m i e r ( ) ) / / ou e l e m==e l e m e n t 4 return r e s t e L i s t e ; 5 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 ; 6 else { 7 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 ) ) ; 8 return t h i s ; 9 } 10 }
  • 10. 10 ˆ ´ CHAPITRE 14. LISTES CHAINEES 14.4 Listes tri´ es e Nous nous int´ ressons maintenant aux listes chaˆn´ es dans lesquelles les el´ ments respectent un e ı e ´e ordre croissant. Dans ce cas, les m´ thodes de recherche, d’insertion et de suppression sont diff´ rentes. e e L’ordre des el´ ments permet d’arrˆ ter plus tˆ t la recherche d’un el´ ment qui n’existe pas dans la liste. ´e e o ´e Aussi, l’insertion ne se fait plus en d´ but de liste, mais a la place qui pr´ serve l’ordre des el´ ments. e ` e ´e Nous utiliserons une classe ListeTriee qui est tr` s similaire a la classe Liste, mais dans la- e ` quelle on s’int´ resse uniquement aux m´ thodes de recherche (contientTriee), d’insertion (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 class ListeTriee { 2 int element ; 3 ListeTriee suivant ; 4 5 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 ){ 6 element = premier ; 7 suivant = reste ; 8 } 9 10 public int premier ( ) { . . . } 11 public ListeTriee reste ( ) { . . . } 12 public v o i d m o d i f i e P r e m i e r ( i n t elem ) { . . . } 13 public 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 ) { . . . } 14 15 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 ) { . . . } 16 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 ) { . . . } 17 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 ) { . . . } 18 } 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 s’arrˆ 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 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 ) { 2 ListeTriee ref=this ; 3 w h i l e ( r e f ! = n u l l && r e f . p r e m i e r ( ) <= elem ) { 4 i f ( r e f . p r e m i e r ( ) == elem ) 5 return true ; 6 else ref=ref . reste (); 7 } 8 return f a l s e ; 9 }
  • 11. ´ 14.4. LISTES TRIEES 11 Variante r´ cursive : e Listing 14.17 – (lien vers le code brut) 1 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 ) { 2 i f ( elem == p r e m i e r ( ) ) r e t u r n t r u e ; 3 i f ( elem < p r e m i e r ( ) ) r e t u r n f a l s e ; 4 ListeTriee resteListe = reste () ; 5 i f ( r e s t e L i s t e == n u l l ) 6 return f a l s e ; 7 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 ) ; 8 } 14.4.2 Insertion dans une liste tri´ e e L’insertion d’un 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 figure 14.5 montre les deux cas d’insertion : – en d´ but de liste. e Elle est similaire alors a l’op´ ration insertionDebut de la classe Liste ` e – en milieu de liste. La recheche de la position d’insertion se fait alors avec une m´ thode similaire a celle uti- e ` 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 modifi´ pour pointer vers la nouvelle cellule, tandis que celle-ci doit e e ˆ e pointer vers la cellule courante (ref). pred ref pred ref liste liste nouvelle liste e1 ... e1 ... ep er ... e e F IG . 14.5 – Insertion dans une liste tri´ e e Dans la figure 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, l’insertion se fait a ee ` e ´e ` la fin de la liste, donc au moment de l’arrˆ 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 figure 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 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 ) { 2 ListeTriee ref=this ; / / r e f e r e n c e qui cherche elem 3 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 4 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 5 pred = r e f ; / / avance pred 6 ref = ref . reste (); / / avance r e f
  • 12. 12 ˆ ´ CHAPITRE 14. LISTES CHAINEES 7 } 8 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 9 r e t u r n new L i s t e T r i e e ( elem , t h i s ) ; 10 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 11 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 ) ; 12 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 13 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 14 } 15 } 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). L’insertion 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, l’insertion se fera en tˆ te de liste. Sinon, ee ` e ´ ` e l’insertion 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 n’est pas vide, l’insertion se fait r´ cursivement dans reste et le r´ sultat ` e e e remplace l’ancien reste. Listing 14.19 – (lien vers le code brut) 1 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 ) { 2 i f ( elem <= p r e m i e r ( ) ) 3 r e t u r n new L i s t e T r i e e ( elem , t h i s ) ; 4 else { 5 ListeTriee resteListe = reste (); 6 i f ( r e s t e L i s t e == n u l l ) 7 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 ) ) ; 8 else 9 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 ) ) ; 10 return t h i s ; 11 } 12 } 14.4.3 Suppression dans une liste tri´ e e La suppression de la premi` re occurrence d’un 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´ ficie du tri des valeurs. Aussi, si plusieurs occurrences de l’´ l´ ment existent, elles e e ee sont forc´ ment l’une a la suite de l’autre 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 :
  • 13. 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 qu’il faut v´ rifier que ref pointe vraiment la valeur ee e e recherch´ e. e Listing 14.20 – (lien vers le code brut) 1 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 ) { 2 Liste ref=this ; / / r e f e r e n c e qui cherche elem 3 L i s t e pred= null ; / / predecesseur , i n i t i a l i s e a nu l l 4 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 5 pred = r e f ; / / avance pred 6 ref = ref . reste (); / / avance r e f 7 } 8 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 9 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 10 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 11 else { / / m i l i e u de l a l i s t e 12 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 13 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 14 } 15 } 16 e l s e return t h i s ; / / e l e m e n t non t r o u v e 17 } 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 d’arrˆ t est rajout´ e : e e quand l’´ l´ ment a eliminer est plus petit que premier, il n’existe sˆ rement pas dans la liste et celle-ci ee `´ u est retourn´ e non modifi´ e. e e Listing 14.21 – (lien vers le code brut) 1 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 ) { 2 Liste resteListe = reste () ; 3 i f ( elem == p r e m i e r ( ) ) 4 return r e s t e L i s t e ; 5 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 6 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 ; 7 else { 8 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 ) ) ; 9 return t h i s ; 10 } 11 } 14.5 Un exemple de programme qui utilise les listes Consid´ rons un exemple simple de programme qui manipule des listes chaˆn´ es en utilisant la e ı e classe Liste.
  • 14. 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 final). La liste doit garder les el´ ments dans l’ordre dans lequel ils sont introduits. ´e Egalement, une valeur ne doit etre stock´ e qu’une 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 l’ordre des el´ ments. Les el´ ments de cette seconde liste ´e ´e devront etre elimin´ s de la liste initiale. ˆ ´ e A la fin, le programme affiche ce qui reste de la premi` re liste. e Remarque : Pour garder les el´ ments dans l’ordre d’introduction, l’insertion d’un nouvel el´ ment ´e ´e doit se faire en fin de liste. La m´ thode insertionDebut ne convient donc pas. La solution e est d’utiliser la m´ thode concatenation. e Remarque : Pour qu’un el´ ment soit stock´ une seule fois dans la liste, il faut d’abord v´ rifier s’il ´e e e n’y est pas d´ j` , a l’aide 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 public cl as s ExempleListes{ 2 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 ) { 3 / / 1. Creation premiere l i s t e 4 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 : ” ) ; 5 Liste l i s t e = null ; / / l i s t e a construire 6 do { 7 i nt val = Terminal . l i r e I n t ( ) ; 8 i f ( v a l ==0) break ; 9 i f ( l i s t e == n u l l ) 10 l i s t e = new L i s t e ( v a l , n u l l ) ; 11 else i f (! l i s t e . contient ( val )) 12 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 ) ) ; 13 } while ( true ) ; 14 15 / / 2. Creation seconde l i s t e 16 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 ) : ” ) ; 17 Liste l i s t e 2 = null ; 18 do { 19 i nt val = Terminal . l i r e I n t ( ) ; 20 i f ( v a l ==0) break ; 21 i f ( l i s t e 2 == n u l l ) 22 l i s t e 2 = new L i s t e ( v a l , n u l l ) ; 23 else l i s t e 2 = l i s t e 2 . insertionDebut ( val ) ; 24 } while ( true ) ; 25 26 / / 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 27 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 ( ) ) { 28 i f ( l i s t e == n u l l ) break ; / / plus rien a eliminer 29 l i s t e = l i s t e . suppressionPremier ( r ef . premier ( ) ) ; 30 } 31 32 / / 4. Affichage l i s t e restante 33 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 : ” ) ; 34 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 ( ) ) 35 Terminal . e c r i r e S t r i n g ( ” ” + r e f . premier ( ) ) ;
  • 15. 14.5. UN EXEMPLE DE PROGRAMME QUI UTILISE LES LISTES 15 36 Terminal . sautDeLigne ( ) ; 37 } 38 }