Cours dAlgorithmique Listes piles et files Arbres Types
Cours d’Algorithmique Listes, piles et files. Arbres. Types de données abstraits. Implantations. 8 novembre 2006 Cours d'algorithmique 2 - Intranet 1
Les grandes lignes du cours • Trier et cher • Listes et arbres • Le back-track • Arbres équilibrés • Récursivité et induction sur la structure • Divide and conquer • Minimax • Dérécursion • Divers problèmes particuliers • Logique de Hoare • Programmation dynamique • Complexité et calculabilité 8 novembre 2006 Cours d'algorithmique 2 - Intranet 2
Voici des listes ! 2 4 0 Tableau 2 2 4 4 6 2 1 6 2 2 8 10 4 8 novembre 2006 10 1 -1 FIN Cours d'algorithmique 2 - Intranet 3
Caractérisations d’une liste ! • Un élément plus un lien vers le suivant. • Séquence ordonnée finie. – Suite ordonnée des mathématiques. • Un tableau peut être vu comme une liste, si on limite les accès aléatoires. – On lit T[0], puis T[1], etc, par exemple. • Une liste est caractérisée par – ses propriétés et fonctions d’accès – et non sa réalisation. 8 novembre 2006 Cours d'algorithmique 2 - Intranet 4
Constructeurs et prédicats sur listes --------------------------------Soit LT le type des listes d’éléments de type T. Le constructeur de la liste vide : cree_vide : void -> LT Le constructeur général : ajout_liste : T x LT -> LT Le prédicat qui distingue les deux cas : est_vide : LT -> BOOL 8 novembre 2006 Cours d'algorithmique 2 - Intranet 5
Constructeurs et prédicats sur listes --------------------------------Les propriétés vérifiées par ces fonctions : est_vide ( cree_vide () ) = Vrai est_vide ( ajout_liste ( e , l ) ) = Faux • La seule liste vide est celle créée par « cree_vide » . • Aucune liste obtenue par adjonction d’un élément « a » à une liste « l » n’est vide. • Salutations de la part de Monsieur de la Palisse ! 8 novembre 2006 Cours d'algorithmique 2 - Intranet 6
Fonctions d’accès sur listes --------------------------------La fonction d’accès à l’élément : tete_liste : LT -> T La fonction d’accès à la suite de la liste : queue_liste : LT -> LT Les propriétés vérifiées par ces fonctions : tete_liste ( ajout_liste ( a , l ) ) = a queue_liste ( ajout_liste ( a , l ) ) = l 8 novembre 2006 Cours d'algorithmique 2 - Intranet 7
Fonctions d’accès sur listes --------------------------------Les limitations d’application de ces fonctions, les appels suivants sont interdits : tete_liste ( cree_vide () ) queue_liste ( cree_vide () ) Ce qui est vraiment caractéristique d’une liste : tete_liste ( ajout_liste ( a , l ) ) = a On parle d’une structure Last In - First Out 8 novembre 2006 Cours d'algorithmique 2 - Intranet (LIFO) 8
Types de données abstraits -------------------------------- • Nous nous sommes donné des noms de types : – un type de base T, – un type de liste LT sur ce type de base. • Nous nous sommes donné des fonctions et leurs propriétés : – cree_vide , . . . , – est_vide ( cree_vide () ) = Vrai , …. • Nous n’avons pas besoin de devenir plus concrets. C’est un type de données abstrait. 8 novembre 2006 Cours d'algorithmique 2 - Intranet 9
Exemple d’implantation --------------------------------ajout_liste ( 5 , 2 5 ajout_liste ( 2 5 ) 1 1 , cree_vide () ) 5 8 novembre 2006 Cours d'algorithmique 2 - Intranet 10
Exemple d’implantation --------------------------------2 1 5 tete_liste ( ) 5 queue_liste ( 5 2 8 novembre 2006 2 1 ) 1 Cours d'algorithmique 2 - Intranet 11
LIFO ! Listes et piles --------------------------------5 5 2 1 ajout_liste = push = empiler tete_liste = top = sommet queue_liste = pop = dépiler 2 1 8 novembre 2006 Pile ( d’assiettes ) stack en anglais Cours d'algorithmique 2 - Intranet 12
Listes et piles : les différences -------------------------------- • Les piles sont restreintes aux opérations : – – – top , pop et push ( et la détection de la pile vide ), celles-ci sont réalisées de façon efficace dans le processeur, par le biais d’un tableau !!! • Les listes peuvent comporter entre autres : – – en plus de ajout_liste , tete_liste et queue_liste (+ liste vide), des fonctions comme inserer_liste , supprimer_liste, … , être doublement chaînées ( cf. TD ) ou circulaires, et ne sont plus des tableaux ! 2 8 novembre 2006 6 4 Cours d'algorithmique 2 - Intranet 13
Listes en langage C --------------------------------#include <stdio. h> #include <stdlib. h> #include <malloc. h> #include <assert. h> typedef int type_base; typedef struct moi_meme {type_base valeur; struct moi_meme *suivant; } t_maillon, *ptr_liste; 8 novembre 2006 Cours d'algorithmique 2 - Intranet 14
Listes en langage C --------------------------------ptr_liste cree_vide (void) { return( (ptr_liste)NULL ); } int est_vide (ptr_liste) { return( liste == (ptr_liste)NULL ); } type_base tete_liste (ptr_liste) {assert( liste != (ptr_liste)NULL ); return( liste->valeur ); } ptr_liste queue_liste (ptr_liste) {assert( liste != (ptr_liste)NULL ); return( liste->suivant ); } 8 novembre 2006 Cours d'algorithmique 2 - Intranet 15
Listes en langage C --------------------------------ptr_liste ajout_liste (type_base elt, ptr_liste) {ptr_liste ptr_auxil; ptr_auxil = (ptr_liste)malloc(sizeof(t_maillon)); ptr_auxil->valeur = elt; ptr_auxil->suivant = liste; return( ptr_auxil ); } ptr_liste 8 novembre 2006 elt Cours d'algorithmique 2 - Intranet liste 16
Exporter les types --- fichier adt_liste. c --------------------------------. . . #include <assert. h> type_liste. h typedef int type_base; typedef struct moi_meme {type_base valeur; struct moi_meme *suivant; } t_maillon, *ptr_liste; #include ‘’type_liste. h ’’ adt_liste. h ptr_liste cree_vide (void); int est_vide (ptr_liste); ptr_liste ajout_liste (type_base elt, ptr_liste); type_base tete_liste (ptr_liste); ptr_liste queue_liste (ptr_liste); #include ‘’adt_liste. h’’ ptr_liste cree_vide (void) { return( (ptr_liste)NULL ); } 8 novembre 2006 . . . Cours d'algorithmique 2 - Intranet 17
Exporter les types --- fichier adt_liste. c --------------------------------. . . #include <assert. h> #include ‘’type_liste. h’’ #include ‘’adt_liste. h’’ ptr_liste cree_vide (void) { return( (ptr_liste)NULL ); } Les définitions viennent ici ! . . . Le fichier adt_liste. c 8 novembre 2006 Cours d'algorithmique 2 - Intranet 18
prog. c qui utilise le type de données liste : --------------------------------. . . #include <assert. h> #include ‘’type_liste. h’’ #include ‘’adt_liste. h’’ int main (void). . . L’utilisateur voit la structure du type de liste. L’utilisateur voit les signatures des fonctions sur les listes. L’utilisateur ne voit pas la réalisation des fonctions, c’est-à-dire le contenu de adt_liste. c ! Souvent, c’est mieux fait dans d’autres langages comme Ada , Modula , C++ et plein d’autres. 8 novembre 2006 Cours d'algorithmique 2 - Intranet 19
Compilation séparée -------------------------------- • gcc –o executable prog. c – – – On ne peut pas générer l’exécutable. On connaît les signatures des fonctions sur les listes. Mais, on ne connaît pas leurs réalisations ! • gcc –o executable prog. c adt_liste. c – On peut compiler les deux fichiers en même temps. • gcc –c prog. c – Nous compilons prog. c pour générer « prog. o » . – Nous n’avons pas besoin des définitions sur les listes, car nous ne créons pas encore l’exécutable. – De même, gcc –c adt_liste. c crée « adt_liste. o » . • gcc –o executable prog. o adt_liste. o 8 novembre 2006 Cours d'algorithmique 2 - Intranet 20
Les fichiers. h -------------------------------- • Les fichiers «. h » donnent les « types » et/ou les « prototypes » . • #include <file. h> – file. h est cherché dans les répertoires standard, – mais aussi dans tout répertoire indiqué par -Irép. – Exemple : gcc … -I. . /local/include … • #include ‘’file. h’’ – file. h est cherché dans le répertoire courant. • gcc -Wmissing-prototypes … – L’absence de prototypes est signalée par un avertissement. 8 novembre 2006 Cours d'algorithmique 2 - Intranet 21
Créer et utiliser les librairies -------------------------------- • Il existe des librairies statiques, dynamiques et archives. – « ar r libadtl. a adt_liste. o » crée la librairie « libadtl. a » à partir du contenu de « adt_liste. o » , – « ar t libadtl. a » affiche le contenu de la librairie. • « gcc -o executable -L. prog. c -ladtl » compile prog. c – Le répertoire. est inspecté lors de la recherche des librairies, – on recherche la librairie libadtl. a • L’ordre des arguments importe : – OK : gcc prog-math. c -lm – KO : gcc -lm prog-math. c 8 novembre 2006 Cours d'algorithmique 2 - Intranet 22
Les files -------------------------------- • LIFO : listes et piles. – Les accès en « ajout » , « lecture » et « suppression » se font en tête de liste : Insertion Lecture Suppression … • FIFO : files. – First In – First Out, c’est plus équitable ! – L’insertion se fait à la fin et c’est la seule différence. Lecture Suppression 8 novembre 2006 … Insertion Cours d'algorithmique 2 - Intranet 23
Les files en langage C --------------------------------ptr_liste ajout_file (type_base elt, ptr_file) {ptr_file ptr_auxil; ptr_auxil = (ptr_file)malloc(sizeof(t_maillon)); ptr_auxil->valeur = elt; ptr_auxil->suivant = (ptr_file)NULL; if ( file == (ptr_file)NULL ) return( ptr_auxil ); else {ptr_file ptr_local = file; while ( ptr_local->suivant != (ptr_file)NULL ) ptr_local = ptr_local->suivant; ptr_local->suivant = ptr_auxil; return( file ); }} 8 novembre 2006 Cours d'algorithmique 2 - Intranet 24
Les files -------------------------------- • Souvent, on maintient deux pointeurs : tête … queue • C’est plus pratique d’avoir une structure de synthèse : file … 8 novembre 2006 Cours d'algorithmique 2 - Intranet 25
Les arbres enracinés --------------------------------racine Il y a un nœud qui est la « racine » . Il y a une orientation de la racine vers les autres. 8 novembre 2006 Cours d'algorithmique 2 - Intranet 26
Les arbres enracinés --------------------------------racine Les feuilles sont les extrémités de l’arbre. Du point de vue de l’arbre, elles sont atomiques (sans successeur). Concernant l’application, elles comportent souvent des valeurs. 13 5 8 novembre 2006 Cours d'algorithmique 2 - Intranet 27
Les arbres enracinés --------------------------------racine Il y a des nœuds (internes) qui ont des « fils » en nombre variable. + x 8 novembre 2006 Cours d'algorithmique 2 - Intranet Chaque fils est à son tour un arbre. Concernant l’application, les nœuds peuvent comporter des valeurs, que l’on appelle aussi des étiquettes. 28
Les arbres enracinés -------------------------------- • Un arbre est – soit, simplement une feuille : racine – soit, un nœud (racine) avec un ou plusieurs fils qui sont des arbres (enracinés) à leur tour : racine arbre 8 novembre 2006 arbre Cours d'algorithmique 2 - Intranet 29
Les arbres enracinés (binaires) comme ADT -------------------------------- • Création d’une feuille : – cree_feuille : void -> A – cree_feuille : int -> A pour créer une feuille qui comporte une valeur entière, avec : valeur_feuille : A -> int • Création d’un nœud binaire : – cree_arbre : A x A -> A – cree_arbre : A x int x A -> A pour créer un nœud qui comporte une étiquette entière, avec : etiquette_arbre : A -> int 8 novembre 2006 Cours d'algorithmique 2 - Intranet 30
Les arbres enracinés (binaires) comme ADT -------------------------------- • Distinction entre feuilles et noeuds : – est_feuille : A -> BOOL est_feuille( cree_feuille() ) = Vrai est_feuille( cree_noeud( x , y ) ) = Faux • Décomposition d’un nœud binaire : – fils_gauche : A -> A – fils_droit : A -> A fils_gauche ( cree_arbre ( g , d ) ) = g fils_droit ( cree_arbre ( g , d ) ) = d 8 novembre 2006 Cours d'algorithmique 2 - Intranet 31
Les arbres enracinés (binaires) comme ADT --------------------------------arbre_un = cree_arbre ( cree_feuille(5) , cree_feuille(7) ); arbre_deux = cree_arbre ( cree_feuille(2) , cree_arbre ( arbre_un , cree_feuille(1) ) ); arbre_trois = cree_arbre ( cree_feuille(3) , cree_feuille(7) ); arbre = cree_arbre ( arbre_deux , arbre_trois ); 2 3 7 1 5 8 novembre 2006 7 Cours d'algorithmique 2 - Intranet 32
Les arbres en langage C -------------------------------- • Un pointeur sur un arbre est : – soit, un pointeur sur une feuille, – soit, un pointeur sur un nœud. • Il faut donc une structure capable de contenir les deux : – – – les champs d’une feuille, les champs d’un nœud, un indicateur booléen qui distingue les deux cas de figure. • Exemple, (expressions arithmétiques) : – toute feuille est un entier, – chaque nœud comporte : • un opérateur parmi « + » , « * » et « - » , • deux fils qui sont des sous-expressions. 8 novembre 2006 Cours d'algorithmique 2 - Intranet 33
Les arbres en langage C --------------------------------typedef struct moi_meme {int est_feuille; int valeur; Si c’est une feuille … vaudra VRAI aura une valeur char etiq; struct moi_meme *fg; struct moi_meme *fd; Ces champs n’ont simplement aucun sens dans ce contexte ! } t_arbre, *ptr_arbre; 8 novembre 2006 Cours d'algorithmique 2 - Intranet 34
Les arbres en langage C --------------------------------typedef struct moi_meme {int est_feuille; vaudra FAUX Si c’est un noeud … int valeur; char etiq; aura une valeur struct moi_meme *fg; aura une valeur struct moi_meme *fd; aura une valeur } t_arbre, *ptr_arbre; Le champ « valeur » n’a simplement aucun sens dans ce contexte ! En Pascal, ADA et d’autres, il existe des structures variables ! 8 novembre 2006 Cours d'algorithmique 2 - Intranet 35
Les arbres en langage C -------------------------------- int est_feuille (ptr_arbre) {return(arbre->est_feuille); } ptr_arbre cree_feuille (int val) {ptr_arbre; arbre = (ptr_arbre)malloc(sizeof(t_arbre)); arbre->est_feuille = 1; arbre->valeur = val; return(arbre); } 8 novembre 2006 Cours d'algorithmique 2 - Intranet 36
Les arbres en langage C --------------------------------ptr_arbre cree_noeud (ptr_arbre fg, ptr_arbre fd, char symbole) {ptr_arbre; arbre = (ptr_arbre)malloc(sizeof(t_arbre)); arbre->est_feuille = 0; arbre->etiq = symbole; arbre->fg = fg; arbre->fd = fd; return(arbre); } 8 novembre 2006 Cours d'algorithmique 2 - Intranet 37
Les arbres en langage C -------------------------------- ptr_arbre fils_gauche (ptr_arbre) {assert( !est_feuille(arbre) ); return(arbre->fg); } ptr_arbre fils_droit (ptr_arbre) {assert( !est_feuille(arbre) ); return(arbre->fd); } 8 novembre 2006 Cours d'algorithmique 2 - Intranet 38
Listes, arbres et le pointeur NULL -------------------------------- • • • Une liste peut être vide ! Elle sera représentée par le pointeur NULL ! La raison profonde est le fait que l’opération de base est : – la concaténation, – qui est associative – et possède la liste vide comme élément neutre ! • Nous avons les fonctions suivantes : – – – cree_vide ajout_liste est_vide tete_liste queue_liste 8 novembre 2006 Cours d'algorithmique 2 - Intranet 39
Listes, arbres et le pointeur NULL -------------------------------- • • • Un arbre n’est jamais NULL ! C’est juste le programmeur qui l’est ! ! ! La raison profonde est le fait que l’opération de base est : – la construction d’arbre, – qui n’est pas associative – et la question de l’élément neutre ne se pose même pas ! Arbre ( A , Arbre ( B , C ) ) =/ Arbre ( A , B ) , C ) A C B 8 novembre 2006 C A Cours d'algorithmique 2 - Intranet B 40
Listes, arbres et le pointeur NULL -------------------------------- • • • Un arbre n’est jamais NULL ! C’est juste le programmeur qui l’est ! ! ! La raison profonde est le fait que l’opération de base est : – la construction d’arbre, – qui n’est pas associative – et la question de l’élément neutre ne se pose même pas ! • Nous avons les fonctions suivantes : – – – cree_feuille cree_noeud est_feuille fils_gauche fils_droit 8 novembre 2006 Cours d'algorithmique 2 - Intranet 41
Listes, arbres et le pointeur NULL -------------------------------- • Je peux éventuellement écrire ceci : typedef struct moi_meme { struct moi_meme fg , fd ; }. . . ptr_arbre cree_feuille (int valeur) {ptr_arbre; arbre = (ptr_arbre)malloc(sizeof(t_arbre)); arbre->fg = NULL ; arbre->fd = (int *) valeur ; return ( arbre ) ; } 8 novembre 2006 Nous utilisons le champ fg pour indiquer que l’arbre est une feuille, . . . et le fils droit pour mémoriser sa valeur ! Cours d'algorithmique 2 - Intranet 42
- Slides: 42