Structures de données simples ============================= Algorithmes sur les structures de données simples .. FIXME - tableaux - listes (les tris) - piles - files +------------------------------------------------------+------------------------------------------------------------------------+ | Contenus | Précisions et commentaires | +======================================================+========================================================================+ | Recherche dans une liste, recherche du maximum dans | | | une liste de nombres, calcul de la moyenne et de la | | | variance. | | +------------------------------------------------------+------------------------------------------------------------------------+ | Recherche d’un mot dans une chaîne de caractères. | On se limite ici à l’algorithme "naïf", en estimant sa complexité. | +------------------------------------------------------+------------------------------------------------------------------------+ Liste ------ .. code-block:: python zoo = ['bear', 'lion', 'panda', 'zebra'] print(zoo) # But these list elements are not biggerZoo = ['bear', 'lion', 'panda', 'zebra', ['chimpanzees', 'gorillas', 'orangutans', 'gibbons']] print(biggerZoo) FIXME - Lists Versus Tuples - Lists Versus Sets Tuples are used to collect an immutable ordered list of elements. This means that: You can’t add elements to a tuple. There’s no append() or extend() method for tuples, You can’t remove elements from a tuple. Tuples have no remove() or pop() method, You can find elements in a tuple since this doesn’t change the tuple. You can also use the in operator to check if an element exists in the tuple. A list stores an ordered collection of items, so it keeps some order. Dictionaries don’t have any order. Dictionaries are known to associate each key with a value, while lists just contain values. Use a dictionary when you have an unordered set of unique keys that map to values. .. code-block:: python >>> listOfStrings = ['One', 'Two', 'Three'] >>> strOfStrings = ' '.join(listOfStrings) >>> print(strOfStrings) One Two Three >>> >>> # List Of Integers to a String ... listOfNumbers = [1, 2, 3] >>> strOfNumbers = ''.join(str(n) for n in listOfNumbers) >>> print(strOfNumbers) 123 >>> Modification de la structure de données ---------------------------------------- .. code-block:: python >>> l = [('host1', '10.1.2.3', '6E:FF:56:A2:AF:18'), ('host3', '10.1.2.5', '6E:FF:56:A2:AF:19')] >>> result = [] >>> for hostname, ip, macaddress in l: ... result.append(dict(hostname=hostname, ip=ip, macaddress=macaddress)) ... >>> result [{'hostname': 'host1', 'ip': '10.1.2.3', 'macaddress': '6E:FF:56:A2:AF:18'}, {'hostname': 'host3', 'ip': '10.1.2.5', 'macaddress': '6E:FF:56:A2:AF:19'}] >>> Structures de données complexes ------------------------------- - graphes - arbres - hachages - le parcours de graphes - les calculs de dates + **Récursivité** On en présente les avantages et les inconvénients. + **Tris** d’un tableau à une dimension de valeurs numériques : tri par insertion, tri rapide (ou 'quicksort'), tri par fusion. Application à la recherche de la médiane d’une liste de nombres. On étudie et on compare ces algorithmes de tri du point de vue des complexités temporelles dans le meilleur et dans le pire cas. Les types produits ------------------- Les types construits permettent de structurer l’information. - les produits (n-uplets) .. code-block:: ocaml # type complexe = float * float ;; - les produits nommés (enregistrements) .. code-block:: ocaml # type adresse = { rue : string ; ville : string ; cp : int};; # type fiche = { nom : string ; prenom : string ; adresse : adresse ; date naissance : int * int * int ; tel fixe : string ; portable : string };; # let v1 = { a = 1 ; b = false ; c = 'r'};; - les sommes (constructeurs) .. code-block:: ocaml # type couleur = Pique | Coeur | Carreau | Trefle;; # let v = (Pique , Coeur);; val v : couleur * couleur = (Pique , Coeur) .. code-block:: ocaml type nombre = Ent of int | Reel of float | Cplx of float × float Ent, Reel, Cplx sont les constructeurs du type. On voit qu'une expression peut-être complexe, mais dans tous les cas une valeur est renvoyée. - les types séquences (listes) .. code-block:: ocaml # 4::1::5::8::1::[];; - : int list = [4 ;1 ;5 ;8 ;1] Algorithme de la longueur d'une liste -------------------------------------- .. code-block:: ocaml # let rec longueur l = match l with [] -> 0 | ::s -> 1 + (longueur s);; Cette fonction est prédéfinie en Ocaml : `List.length` Algorithmes de tri ------------------ On désigne par "tri" l'opération consistant à ordonner un ensemble d'éléments en fonction de clés sur lesquelles est définie une relation d'ordre. Les algorithmes de tri ont une grande importance pratique. Ils sont fondamentaux dans certains domaines (exemples : map-reduce en database non relationnelle). L'étude du tri est également intéressante en elle-même, c'est un des domaines de l'algorithmique très étudié et connu. Tri par insertion ~~~~~~~~~~~~~~~~~~ Cet algorithme de tri suit de manière naturelle la structure récursive des listes. Soit l une liste à trier : - si l est vide alors elle est déjà triée - sinon, l est de la forme x::s et on trie récursivement la suite s et on obtient une liste triée s’ on insert x au bon endroit dans s’ et on obtient une liste triée Description de l'algorithme - la fonction inserer permet d’insérer un élément x dans une liste l - si la liste l est triée alors x est inséré au bon endroit .. code-block:: ocaml # let rec inserer x l = match l with [] -> [x] | y::s -> if x<=y then x::l else y::(inserer x s);; val inserer : ’a -> ’a list -> ’a list # inserer 5 [3 ;7 ;10];; - : int list = [3 ; 5 ; 7 ; 10] Tri rapide ~~~~~~~~~~~~ soit une liste l à trier : - si l est vide alors elle est triée - sinon, choisir un élément p de la liste (le premier par exemple) nommé le **pivot** - partager l en deux listes g et d contenant les autres éléments de l qui sont plus petits (resp. plus grands) que la valeur du pivot p - trier récursivement g et d, on obtient deux listes g’ et d’ triées .. code-block:: ocaml :caption: fonction de partage d'une liste #let rec partage p l = match l with [] -> ([] , []) |x::s -> let g,d = partage p s in if x<=p then (x::g , d) else (g , x::d) ;; val partage : ’a -> ’a list -> ’a list * ’a list = # partage 5 [1 ;9 ;7 ;3 ;2 ;4];; - : int list * int list = ([1 ; 3 ; 2 ; 4], [9 ; 7]) .. code-block:: ocaml :caption: algorithme de tri rapide # let rec tri rapide l = match l with [] -> [] | p::s -> let g , d = partage p s in (tri rapide g)@[p]@(tri rapide d) ;; val tri rapide : ’a list -> ’a list = # tri rapide [5 ; 1 ; 9 ; 7 ; 3 ; 2 ; 4];; - : int list = [1 ; 2 ; 3 ; 4 ; 5 ; 7 ; 9] Les listes chaînées ~~~~~~~~~~~~~~~~~~~~ .. code-block:: ocaml typedef struct list{ int elt ; struct list* suivant ; } ;