Cours num´ero 5 : Les listes Introduction aux listes Les listes
Transcription
Cours num´ero 5 : Les listes Introduction aux listes Les listes
Introduction aux listes Liste : définition Collection ordonnée d’éléments [x1 ; ....; xn ] (au moins) accessibles l’un après l’autre de x1 jusqu’à xn . Cours numéro 5 : Les listes LI213 – Types et Structures de données Exemple : dans la liste [2 ;3 ;5 ;1 ;6], on peut accéder à Christophe Gonzales – Pierre-Henri Wuillemin «2». À partir de «2», on peut accéder à «3», et ainsi de suite. Licence d’Informatique – Université Paris 6 Cette définition ne présuppose rien sur la représentation en mémoire. En principe, pas de contrainte sur le nombre d’éléments dans la liste. Christophe Gonzales – Pierre-Henri Wuillemin Les listes simplement chaı̂nées Intérêt des listes chaı̂nées (1/2) Définition Définition récursive : une liste est composée d’un élément (la tête) suivi par la liste des éléments suivants (la queue). Illustration graphique : x1 x2 x3 ..... xn Les seuls opérateurs : Un opérateur pour accéder à la tête : car en LISP/Scheme, hd en OC AML. Un opérateur pour accéder à la queue : cdr en LISP/Scheme, tl en OC AML. toujours faire un dessin indiquant comment sont chaı̂nés les éléments. Vous pensez pouvoir vous en passer ? OK, vous aurez des bugs, à vous de voir.... Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Cours numéro 5 : Les listes x1 x2 ..... x3 xn Les flèches sont des pointeurs =⇒ en mémoire, les boites ne sont pas placées les unes à côté des autres Avantages des listes simplement chaı̂nées Suppression d’un élément facile et rapide : parcourir la liste jusqu’à l’élément à supprimer puis rechaı̂ner x1 x2 x3 ..... xn On peut rajouter autant d’éléments que l’on veut Utilisation d’un espace mémoire proportionnel au nombre d’éléments (=⇒ pas de perte de mémoire) Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Inconvénients des listes chaı̂nées (2/2) x1 x2 ..... x3 Les listes doublement chaı̂nées Définition Similaire à une liste simplement chaı̂née sauf qu’on peut aussi accéder au prédécesseur. xn Illustration graphique : Inconvénients des listes simplement chaı̂nées Temps d’accès aux éléments : il faut en moyenne parcourir n/2 éléments avant de trouver un élément donné. x1 x2 x3 ..... xn Inconvénients du double chaı̂nage par rapport au simple chaı̂nage : Conclusion : utilisation C’est une structure à utiliser : 1 2 chaı̂nage plus complexe à gérer (2 pointeurs au lieu d’un) utilise plus de mémoire quand effectue souvent des ajouts/suppressions d’éléments, Avantages du double chaı̂nage par rapport au simple chaı̂nage : quand on ne sait pas a priori combien on aura d’objets xi Christophe Gonzales – Pierre-Henri Wuillemin Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Les listes circulaires Cours numéro 5 : Les listes bilan : comparaison avec les tableaux Définition Listes telles que le «dernier» élément de la liste a pour suivant le «premier» Illustration graphique : x2 suppression d’un élément plus rapide : rechaı̂ner autour de l’élément à supprimer =⇒ parcours de liste inutile x2 x3 x1 x3 x1 xn liste circulaire simplement chaı̂née xn liste circulaire doublement chaı̂née liste nb d’éléments arbitraire accès aux éléments lent (parcours) insertion au début rapide insertion en fin lente (parcours) insertion au milieu lente (parcours) suppression rapide (rechaı̂nage) tableau borné rapide lente (décalages) rapide lente (décalages) lente (décalages) Règle : Utiliser plutôt des tableaux sauf si : on doit faire beaucoup de suppressions Utilisation : exécution de threads (fonctions s’exécutant en concurrence (≈ en parallèle)) Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes on ne connaı̂t pas le nombre d’éléments maximal a priori Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Listes en OC AML Parcours d’une liste (1/2) type ’a list d’OC AML : listes simplement chaı̂nées La Core Library [] = la liste vide [6 ; 7 ; 2] = liste de 3 entiers :: concaténation d’un élément avec une liste : 1 :: [2 ;3 ;4] = [1 ;2 ;3 ;4] @ concaténation de listes : [1 ;2] @ [3 ;4] = [1 ;2 ;3 ;4] Librairie standard : le module List hd : ’a list -> ’a : renvoie la tête de la liste tl : ’a list -> ’a list : renvoie la queue de la liste Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes # open List ;; let rec somme liste = if liste = [] then 0 else hd liste + somme (tl liste) ;; #trace somme ;; somme [5 ; 6 ; 7];; val somme somme <-somme <-somme <-somme <-somme --> somme --> somme --> somme --> - : int = : int list -> int = <fun> [5 ; 6 ; 7] [6 ; 7] [7] [] tester la fin de la récursion 0 avant l’appel récursif 7 13 18 18 Christophe Gonzales – Pierre-Henri Wuillemin Parcours d’une liste (2/2) Cours numéro 5 : Les listes Parcours d’une listes Définition d’une liste en OC AML type ’a list = [] | ’a :: ’a list type somme - cf. cours 6 Règle 1 : Parcourez les listes en utilisant le matching plutôt que hd et tl =⇒ possibilité de matching : match liste with [] -> liste = liste vide match liste with x :: reste -> Règle 2 : Profitez au maximum de la puissance du matching ! x = tête de liste reste = queue de liste # let rec somme liste = match liste with | [] -> 0 | tete :: queue -> tete + somme queue ;; Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Exemple de parcours Parcours simultané de 2 listes Recherche du dernier élément d’une liste : # let rec dernier liste = match liste with | [ x ] -> x | tete :: queue -> dernier queue | [] -> failwith "liste vide";; Recherche de l’avant-dernier élément : # let rec avant dernier liste = match liste with | x :: y :: [] -> x | tete :: queue -> avant dernier queue -> failwith "pas assez d’éléments";; | # let liste1 = [1 ; 2 ; 3 ; 4] and liste2 = [5 ; 6] ;; let rec ajoute l1 l2 = match (l1,l2) with | l1,[] -> l1 | [],l2 -> l2 | tete1 :: queue1, tete2 ::queue2 -> (tete1 + tete2) :: ajoute queue1 queue2 ;; ajoute liste1 liste2;; - : int list = [6 ; 8 ; 3 ; 4] ajoute [1 ; 2 ; 3 ; 4] [5 ; 6] (1 + 5) :: (ajoute [2 ; 3 ; 4] [6]) (2 + 6) :: (ajoute [3 ; 4] []) [3 ; 4] [6 ; [6 ; [8 ; [3 ; 8 ; 3 ; 4] 8 ; 3 ; 4] 3 ; 4] 4] Le « » filtre n’importe quel motif ! Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Rappel : identifiants dans le matching # let position liste elt = let rec recherche liste nb = match liste with | elt :: reste -> nb | tete :: reste -> recherche reste (nb+1) | [] -> failwith "élément non trouvé" in recherche liste 0 ;; position [1 ; 2 ; 3 ; 4] 3;; val position : ’a list -> ’b -> int = <fun> - : int = 0 Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Insertion en début de liste # let insere debut liste elt = elt : : liste ;; let maliste = [2 ; 3 ; 4] ;; insere debut maliste 1;; val insere debut : ’a list -> ’a -> ’a list = <fun> val maliste : int list = [2 ; 3 ; 4] - : int list = [1 ; 2 ; 3 ; 4] Remarques : insertion rapide (pas de parcours de liste) ne modifie pas la liste mais retourne une nouvelle liste éléments partagés avec maliste Retourne 0 au lieu de 2 Rappel : maliste les identifiants qui apparaissent dans les motifs sont non liés. Le filtrage les lie localement à des parties de la valeur filtrée. Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes liste retournée 2 3 1 Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes 4 Insertion en fin de liste Insertion après un élément # let rec insere fin liste elt = match liste with | tete :: queue -> tete :: insere fin queue elt | [] -> [elt] ;; let maliste = [2 ; 3 ; 4] ;; insere fin maliste 1;; Remarques : # let rec insere apres liste elt after = match liste with | tete :: queue -> if tete = after then after :: elt :: queue else tete :: insere apres queue elt after | [] -> [] ;; insere apres [2 ; 3 ; 5 ; 6] 4 3;; - : int list = [2 ; 3 ; 4 ; 5 ; 6] insertion lente : parcours de liste Remarques : retourne une nouvelle liste insertion lente : parcours de liste aucun élément partagé avec maliste retourne une nouvelle liste maliste liste retournée 2 3 4 2 3 4 Christophe Gonzales – Pierre-Henri Wuillemin fin de liste partagée avec maliste maliste 1 Cours numéro 5 : Les listes liste retournée 2 2 3 3 4 Christophe Gonzales – Pierre-Henri Wuillemin Suppression en début de liste 6 5 Cours numéro 5 : Les listes Suppression en fin de liste # let suppression debut liste = match liste with | tete :: queue -> queue | [] -> [] ;; let maliste = [1 ; 2 ; 3 ; 4] ;; suppression debut maliste;; # let rec suppression fin liste = match liste with | [ ] -> [] | tete :: queue -> tete :: suppression fin queue | [] -> [] ;; suppression fin [1 ; 2 ; 3 ; 4];; - : int list = [1 ; 2 ; 3] - : int list = [2 ; 3 ; 4] Remarques : suppression lente : parcours de liste Remarques : suppression rapide (pas de parcours) retourne une nouvelle liste ne modifie pas la liste mais retourne une liste partagée aucun élément partagé avec maliste maliste 1 2 3 maliste 4 liste retournée 1 2 3 1 2 3 liste retournée Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes 4 Suppression après un élément Fonction iter # let rec suppr apres liste after = match liste with | un :: deux :: queue -> if un = after then un :: queue else un :: suppr apres (deux :: queue) after | -> liste ;; suppr apres [2 ; 3 ; 4 ; 5 ; 6] 3;; Définition iter : (’a -> unit) -> ’a list -> unit iter f [a1 ; ... ; an] applique la fonction f à tour de rôle à a1, puis a2, etc. équivalent à (f a1 ; f a2 ; ... ; f an ; ()) - : int list = [2 ; 3 ; 5 ; 6] Exemple # let f x = print string ("nombre : " ˆ string of int x ˆ "\n") ;; List.iter f [1 ; 2 ; 3 ; 4];; Remarques : suppression lente : parcours de liste retourne une nouvelle liste fin de liste partagée avec maliste maliste 2 3 liste retournée 2 3 Christophe Gonzales – Pierre-Henri Wuillemin 4 5 6 nombre : nombre : nombre : nombre : - : unit Cours numéro 5 : Les listes Fonction map 1 2 3 4 = () Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Fonction fold left Définition map : (’a -> ’b) -> ’a list -> ’b list Définition fold left : (’a -> ’b -> ’a) -> ’a -> ’b list -> ’a fold left f a [b1 ; ... ; bn] retourne la valeur de l’expression f (... (f (f a b1) b2) ...) bn f [a1 ;... ;an] retourne la liste [f a1 ;... ;f an] Exemples Exemples # List.map string of int [1 ; 2 ; 3 ; 4];; - : string list = ["1" ; "2" ; "3" ; "4"] # let f str nb = str ˆ " " ˆ (string of int nb) ;; List.fold left f "nombre :" [1 ; 2 ; 3 ; 4];; - : string = "nombre : 1 2 3 4" # let f x = x * x ;; List.map f [1 ; 2 ; 3 ; 4];; - : int list = [1 ; 4 ; 9 ; 16] # let somme nb1 nb2 = nb1 + nb2 ;; List.fold left somme 0 [1 ; 2 ; 3 ; 4] ;; List.fold left (+) 0 [1 ; 2 ; 3 ; 4];; 10 10 Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes Fonction fold right Définition fold right : (’a -> ’b -> ’b) -> ’a list -> ’b -> ’b fold right f [a1 ; ... ; an] b retourne la valeur de l’expression f a1 (f a2 (... (f an b) ...)) Exemple # let f nb str = str ˆ " " ˆ (string of int nb) ;; List.fold right f [1 ; 2 ; 3 ; 4] "nombre :";; - : string = "nombre : 4 3 2 1" Christophe Gonzales – Pierre-Henri Wuillemin Cours numéro 5 : Les listes