420 likes | 726 Views
Cours d’Algorithmique. Listes, piles et files. Arbres. Types de données abstraits. Implantations. Les grandes lignes du cours. Trier et chercher Listes et arbres Le back-track Arbres équilibrés Récursivité et induction sur la structure Divide and conquer Minimax Dérécursion
E N D
Cours d’Algorithmique Listes, piles et files. Arbres. Types de données abstraits. Implantations. Cours d'algorithmique 2 - Intranet
Les grandes lignes du cours • Trier et chercher • 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é Cours d'algorithmique 2 - Intranet
Voici des listes ! 2 4 2 1 0 2 4 6 8 10 Tableau 4 6 2 2 2 10 1 -1 4 FIN Cours d'algorithmique 2 - Intranet
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. Cours d'algorithmique 2 - Intranet
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 Cours d'algorithmique 2 - Intranet
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 ! Cours d'algorithmique 2 - Intranet
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 Cours d'algorithmique 2 - Intranet
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 (LIFO) Cours d'algorithmique 2 - Intranet
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. Cours d'algorithmique 2 - Intranet
2 1 2 1 5 5 Exemple d’implantation----------------------------------------------------------------- ajout_liste( 5 , ) ajout_liste( 5 , cree_vide () ) Cours d'algorithmique 2 - Intranet
tete_liste( ) 5 2 1 5 Exemple d’implantation----------------------------------------------------------------- queue_liste( ) 2 1 5 2 1 Cours d'algorithmique 2 - Intranet
5 1 2 LIFO ! Listes et piles----------------------------------------------------------------- ajout_liste = push = empiler tete_liste = top = sommet queue_liste = pop = dépiler 5 2 Pile ( d’assiettes ) stack en anglais 1 Cours d'algorithmique 2 - Intranet
6 4 2 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 ! Cours d'algorithmique 2 - Intranet
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; Cours d'algorithmique 2 - Intranet
Listes en langage C----------------------------------------------------------------- ptr_liste cree_vide (void) { return( (ptr_liste)NULL ); } int est_vide (ptr_liste liste) { return( liste == (ptr_liste)NULL ); } type_base tete_liste (ptr_liste liste) {assert( liste != (ptr_liste)NULL ); return( liste->valeur ); } ptr_liste queue_liste (ptr_liste liste) {assert( liste != (ptr_liste)NULL ); return( liste->suivant ); } Cours d'algorithmique 2 - Intranet
Listes en langage C----------------------------------------------------------------- ptr_liste ajout_liste (type_base elt, ptr_liste liste) {ptr_liste ptr_auxil; ptr_auxil = (ptr_liste)malloc(sizeof(t_maillon)); ptr_auxil->valeur = elt; ptr_auxil->suivant = liste; return( ptr_auxil );} liste ptr_liste elt Cours d'algorithmique 2 - Intranet
Exporter les types --- fichier adt_liste.c----------------------------------------------------------------- ... #include <assert.h> typedef int type_base; typedef struct moi_meme {type_base valeur; struct moi_meme *suivant; } t_maillon, *ptr_liste; ptr_liste cree_vide (void); int est_vide (ptr_liste liste); ptr_liste ajout_liste (type_base elt, ptr_liste liste); type_base tete_liste (ptr_liste liste); ptr_liste queue_liste (ptr_liste liste); ptr_liste cree_vide (void) { return( (ptr_liste)NULL ); } ... type_liste.h #include ‘’type_liste.h ’’ adt_liste.h #include ‘’adt_liste.h’’ Cours d'algorithmique 2 - Intranet
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 Cours d'algorithmique 2 - Intranet
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. Cours d'algorithmique 2 - Intranet
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 Cours d'algorithmique 2 - Intranet
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. -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. Cours d'algorithmique 2 - Intranet
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 Cours d'algorithmique 2 - Intranet
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 Insertion … … Les files----------------------------------------------------------------- Cours d'algorithmique 2 - Intranet
Les files en langage C----------------------------------------------------------------- ptr_liste ajout_file (type_base elt, ptr_file 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 ); }} Cours d'algorithmique 2 - Intranet
Souvent, on maintient deux pointeurs : tête queue • C’est plus pratique d’avoir une structure de synthèse : file … … Les files----------------------------------------------------------------- Cours d'algorithmique 2 - Intranet
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. Cours d'algorithmique 2 - Intranet
racine Les arbres enracinés----------------------------------------------------------------- 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 Cours d'algorithmique 2 - Intranet
racine Les arbres enracinés----------------------------------------------------------------- Il y a des nœuds (internes) qui ont des « fils » en nombre variable. Chaque fils est à son tour un arbre. Concernant l’application, les nœuds peuvent comporter des valeurs, que l’on appelle aussi des étiquettes. + x Cours d'algorithmique 2 - Intranet
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 arbre arbre Cours d'algorithmique 2 - Intranet
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 Cours d'algorithmique 2 - Intranet
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 Cours d'algorithmique 2 - Intranet
5 7 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 Cours d'algorithmique 2 - Intranet
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. Cours d'algorithmique 2 - Intranet
Les arbres en langage C----------------------------------------------------------------- typedef struct moi_meme {int est_feuille; vaudra VRAI int valeur; aura une valeur char etiq; struct moi_meme *fg; struct moi_meme *fd; } t_arbre, *ptr_arbre; Si c’est une feuille … Ces champs n’ont simplement aucun sens dans ce contexte ! Cours d'algorithmique 2 - Intranet
Les arbres en langage C----------------------------------------------------------------- typedef struct moi_meme {int est_feuille; vaudra FAUX 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; Si c’est un noeud … Le champ « valeur » n’a simplement aucun sens dans ce contexte ! En Pascal, ADA et d’autres, il existe des structures variables ! Cours d'algorithmique 2 - Intranet
Les arbres en langage C----------------------------------------------------------------- int est_feuille (ptr_arbre arbre) {return(arbre->est_feuille); } ptr_arbre cree_feuille (int val) {ptr_arbre arbre; arbre = (ptr_arbre)malloc(sizeof(t_arbre)); arbre->est_feuille = 1; arbre->valeur = val; return(arbre); } Cours d'algorithmique 2 - Intranet
Les arbres en langage C----------------------------------------------------------------- ptr_arbre cree_noeud (ptr_arbre fg, ptr_arbre fd, char symbole) {ptr_arbre arbre; arbre = (ptr_arbre)malloc(sizeof(t_arbre)); arbre->est_feuille = 0; arbre->etiq = symbole; arbre->fg = fg; arbre->fd = fd; return(arbre); } Cours d'algorithmique 2 - Intranet
Les arbres en langage C----------------------------------------------------------------- ptr_arbre fils_gauche (ptr_arbre arbre) {assert( !est_feuille(arbre) ); return(arbre->fg); } ptr_arbre fils_droit (ptr_arbre arbre) {assert( !est_feuille(arbre) ); return(arbre->fd); } Cours d'algorithmique 2 - Intranet
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 Cours d'algorithmique 2 - Intranet
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 ( Arbre ( A , B ) , C ) / A C B C A B Cours d'algorithmique 2 - Intranet
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 Il n'y a pas de fonctions : cree_arbre_vide est_arbre_vide Cours d'algorithmique 2 - Intranet
Listes, arbres et le pointeur NULL----------------------------------------------------------------- C'est juste de la mauvaise programmation ! ! ! • Je peux éventuellement écrire ceci : typedef struct moi_meme { struct moi_meme fg , fd ; } . . . ptr_arbre cree_feuille (int valeur) {ptr_arbre arbre; arbre = (ptr_arbre)malloc(sizeof(t_arbre)); arbre->fg = NULL ; arbre->fd = (int *) valeur ; return ( arbre ) ; } 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