algorithmique cours ensg 2a, septembre 2002 guillaume caumon caumon/teach
TRANSCRIPT
AlgorithmiqueAlgorithmique
Cours ENSG 2A, Septembre 2002Cours ENSG 2A, Septembre 2002
Guillaume CaumonGuillaume Caumon
http://www.ensg.inpl-nancy.fr/~caumon/Teach
IntroductionIntroduction
Algorithme = suite d’actions que devra Algorithme = suite d’actions que devra effectuer un automate pour arriver effectuer un automate pour arriver àà partir d’un partir d’un éétat initial, en un temps fini, tat initial, en un temps fini, àà un run réésultatsultat
Un cours d’algorithmique a Géol… !???Un cours d’algorithmique a Géol… !???
PlanPlan
MMéémoire, pointeurs (1h)moire, pointeurs (1h) Organisation d’un programme (1h)Organisation d’un programme (1h) Structures de donnStructures de donnéées: listes, arbres, es: listes, arbres,
tables... (8h)tables... (8h) Algorithmique: exemple des tris (2h)Algorithmique: exemple des tris (2h)
Partie IPartie ILa mLa méémoiremoire
Les mLes méémoires...moires...
RAM (Random Access Memory): 32 / RAM (Random Access Memory): 32 / 64 Mo64 Mo
Le disque dur: quelques GoLe disque dur: quelques Go
La mLa méémoire virtuelle: temps d’accmoire virtuelle: temps d’accèès s 1000 fois plus long.1000 fois plus long.
MMéémoire et exmoire et exéécutioncution
CodeCode
Données statiquesDonnées statiques
TasTas
Code objet du programmeCode objet du programme
Valeurs constantesValeurs constantes
Piles d’appels de fonctionsPiles d’appels de fonctions
Allocation dynamique deAllocation dynamique demémoiremémoire
PilePile
IntIntéérrêêts des pointeursts des pointeurs
Gestion de l’espace méémoire en cours d’exéécution
Repréésentation de tableaux: accèès direct et indexéé
Modifications de variables passéées en paramèètres de fonction
Rééféérences croiséées
Fonctions virtuelles en programmation objet
Rappels sur les pointeursRappels sur les pointeurs
int* a;int* a;
DDééclarationclaration d’un pointeur vers un entier d’un pointeur vers un entier
aa
Rappels sur les pointeursRappels sur les pointeurs
int* a;int* a;
DDééclaration claration d’un pointeur vers un entierd’un pointeur vers un entier et initialisationet initialisation à “NULL”à “NULL”
int* a = NULL;int* a = NULL;
aa
malloc(3*sizeof(int));malloc(3*sizeof(int));
Allocation dynamiqueAllocation dynamique de place m de place méémoiremoire(pour 3 entiers)(pour 3 entiers)
Rappels sur les pointeursRappels sur les pointeurs
int* a = malloc(3*sizeof(int));int* a = malloc(3*sizeof(int));
Allocation dynamique Allocation dynamique etet assignement assignement
int* a = (int*)malloc(3*sizeof(int));int* a = (int*)malloc(3*sizeof(int));
Rappels sur les pointeursRappels sur les pointeurs
aa *a*a
DDéésallocationsallocation dynamique dynamique
free(a);free(a);
Rappels sur les pointeursRappels sur les pointeurs
aa
a = NULL;a = NULL;
*a*a
int* a = (int*)malloc(3*sizeof(int));int* a = (int*)malloc(3*sizeof(int));
int* a = (int*)calloc(3, sizeof(int));int* a = (int*)calloc(3, sizeof(int));
Rappels sur les pointeursRappels sur les pointeurs
a = (int*)realloc(4*sizeof(int));a = (int*)realloc(4*sizeof(int));
Partie IIPartie IISurvol d’architecture logicielleSurvol d’architecture logicielle
Programme ??Programme ??
Programme
includeFichiers de description (header)Fichiers de description (header)
.h.h
src
Fichiers d’implantation (source code)Fichiers d’implantation (source code).c.c
lib
Librairies et fichiers objetsLibrairies et fichiers objets
bin ExExéécutable(s)cutable(s)a.outa.out .exe.exe
.o.o .so.so ..liblib ..dlldll
But du JeuBut du Jeu
Application, qui parle Application, qui parle directement a directement a l’ordinateurl’ordinateur
Fichiers source = Fichiers source = Instructions dans un Instructions dans un langage de langage de programmationprogrammation
ProblProblèèmes a rmes a réésoudresoudre
tempstemps
tailletaille
ComplexitComplexité,é,CoûtCoût de maintenance de maintenance
Organisation et réutilisation…Organisation et réutilisation…
Organisation du code :Organisation du code :– En fonctions, structures, etc.En fonctions, structures, etc.– En fichiersEn fichiers
Réutilisation :Réutilisation :–Du code (fichiers source)Du code (fichiers source)–Des fichiers binairesDes fichiers binaires
Réutilisation d’un programme Réutilisation d’un programme àà l’autre l’autre
Programmes et librairiesProgrammes et librairies
En C :En C :Exécutable Exécutable ↔ ↔ main()main()
Pour la réutilisation, on utilise des bibliothèques Pour la réutilisation, on utilise des bibliothèques (ou (ou librairieslibrairies) de fonctions : d’une description de ) de fonctions : d’une description de chaque fonction (dans des fichier “.h” d’en-tête, ou chaque fonction (dans des fichier “.h” d’en-tête, ou headerheader), et du code compilé correspondant (des ), et du code compilé correspondant (des “.lib” et “.dll” sous PC, des “.so” et “.a” sous UNIX)“.lib” et “.dll” sous PC, des “.so” et “.a” sous UNIX)
La Compilation : RLa Compilation : Réésumsuméé
Code source CCode source C
Code pré-processéCode pré-processé
exécutableexécutable
LibrairiesLibrairies
Fichier(s) ObjetFichier(s) Objet
.o.o
.so.so.lib.lib
.h.h.c.c
a.outa.out .exe.exe
Fichiers Fichiers d’en-tête Cd’en-tête C
PréprocesseurPréprocesseur
Editeur de liensEditeur de liens
CompilateurCompilateur
QualitQualitéé d’un programme d’un programme
Architecture claireArchitecture claireRéutilisabilitéRéutilisabilité
Structures de donnStructures de donnéées +es +Algorithmes +Algorithmes +Documentation +Documentation +Tests de robustesse +Tests de robustesse +
Partie IIIPartie IIIIntroduction aux structures de Introduction aux structures de
donndonnééeses
““Comment Organiser au Mieux l’InformationComment Organiser au Mieux l’Informationdans un Programme ?”dans un Programme ?”
IntroductionIntroduction
ProblProblèème mme méétaphysique:taphysique:
TableauxTableauxint tab[10];int tab[10]; struct Data_t {struct Data_t {
int index_;int index_; char* value_;char* value_;} Data_t;} Data_t;
StructuresStructures Structures de Structures de donndonnéées es
Les tableauxLes tableaux
Taille fixe, en généralTaille fixe, en général
Réajustement de taille coûteux en tempsRéajustement de taille coûteux en temps
Insertion d’élément onéreuse en temps.Insertion d’élément onéreuse en temps.
AccAccèès indexé s indexé (de 0 à n-1 pour un tableau de n éléments)(de 0 à n-1 pour un tableau de n éléments)
Stockage compactStockage compact
Liste chaînée : SpListe chaînée : Spécificationsécifications
Créer une liste videCréer une liste vide
Ajouter un élément (début / fin / milieu)Ajouter un élément (début / fin / milieu)
Retirer un élément (début / fin / milieu)Retirer un élément (début / fin / milieu)
Détruire une listeDétruire une liste
Trier les éléments d’une listeTrier les éléments d’une liste
Liste chaînée : StructuresListe chaînée : Structures
TTêteête
NoeudNoeud
TTêteête
NoeudNoeud
Liste chaînée : StructuresListe chaînée : Structures
List_tList_t
p_firstp_first
p_lastp_last
nb_elementsnb_elements
Node_tNode_t
p_datap_data p_nextp_next
Data_tData_t
Liste chaînée : HeaderListe chaînée : Header
typedef struct List_t {typedef struct List_t { struct Node_t* p_first_;struct Node_t* p_first_; struct Node_t* p_last_;struct Node_t* p_last_; int nb_elements_;int nb_elements_;} List_t;} List_t;
typedef struct Node_t {typedef struct Node_t { struct Data_t* p_data_;struct Data_t* p_data_; struct Node_t* p_next_;struct Node_t* p_next_;} Node_t;} Node_t;
typedef struct Data_t {typedef struct Data_t { ......} Data_t;} Data_t;
Liste chaînée : HeaderListe chaînée : Header
List_t* list_create( void ); List_t* list_create( void );
int list_insert_item(int list_insert_item(List_t* list, Data_t* itemList_t* list, Data_t* item
););int list_append_item(int list_append_item( List_t* list, Data_t* itemList_t* list, Data_t* item););int list_insert_item_before( int list_insert_item_before(
List_t* list,List_t* list,Data_t* to_insert,Data_t* to_insert,
Data* list_itemData* list_item););
Liste chaînée : HeaderListe chaînée : Header
int list_destroy( List_t* list ); int list_destroy( List_t* list );
Data_t* list_remove_head( List_t* list );Data_t* list_remove_head( List_t* list );
int list_empty( List_t* list ); int list_empty( List_t* list );
Data_t* list_remove_tail( List_t* list );Data_t* list_remove_tail( List_t* list );
int list_remove_item( int list_remove_item( List_t* listList_t* listData_t* itemData_t* item
););
int list_sort( List_t* list );int list_sort( List_t* list );
Liste chaînée : UtilisationListe chaînée : Utilisation
Avant d’aller plus loin, vérifions si nos Avant d’aller plus loin, vérifions si nos spécifications sont suffisantes...spécifications sont suffisantes...
Pour cela, nous allons écrire un programme qui Pour cela, nous allons écrire un programme qui utilise les fonctions du fichier list.h, sans nous utilise les fonctions du fichier list.h, sans nous préoccuper de la façon dont elles sont implantées.préoccuper de la façon dont elles sont implantées.
But du programme: construire et trier une liste But du programme: construire et trier une liste d’entiers par ordre croissant.d’entiers par ordre croissant.
Liste chaînée : ImplantationListe chaînée : Implantation
Cf. code écrit au tableau;Cf. code écrit au tableau;pour résumer les principales règles à suivre:pour résumer les principales règles à suivre:
• Toujours tester la validité d’un pointeur avant Toujours tester la validité d’un pointeur avant de l’utiliser.de l’utiliser.
• S’assurer de ne jamais perdre l’adresse d’une S’assurer de ne jamais perdre l’adresse d’une zone allouée dynamiquement.zone allouée dynamiquement.
• Dans un programme, toute allocation parDans un programme, toute allocation par mallocmalloc ouou calloc calloc doit être suivie d’une doit être suivie d’une désallocation pardésallocation par freefree
Liste chaînée : SpécialisationsListe chaînée : Spécialisations
Pile, ou Tas (Stack): structure LIFOPile, ou Tas (Stack): structure LIFO
void push(Data_t*)void push(Data_t*) Data_t* pop(void)Data_t* pop(void)
Liste chaînée : SpécialisationsListe chaînée : Spécialisations
File, ou queue : structure FIFOFile, ou queue : structure FIFO
void push(Data_t*)void push(Data_t*) Data_t* pop(void)Data_t* pop(void)
Introduction à la complexitéIntroduction à la complexité
Annuaire avec noms et coordonnéesAnnuaire avec noms et coordonnées
temps ttemps t
nombre d’abonnés Nnombre d’abonnés N
t = a · Nt = a · N
t = a · 2t = a · 2NNt = a · Nt = a · N22
t = a · logNt = a · logN
Sets ou Bags et tablesSets ou Bags et tables
Stocker une seule fois le même élémentStocker une seule fois le même élémentdans le conteneur.dans le conteneur.
Pas d’ordrePas d’ordre
Accès rapideAccès rapide
Tables : Associent une clé a un élémentTables : Associent une clé a un élémentdans le conteneur.dans le conteneur.
Besoin de fonctions de hachageBesoin de fonctions de hachage
Structures de donnStructures de donnéées lines linéaireséaires
TableauxTableaux
Sets, BagsSets, Bags
Listes chaListes chaînéesînées
TablesTables
Taille fixeTaille fixeAccAccèès directs direct
Taille variableTaille variableAccAccèès ss séquentieléquentiel
UnicitUnicité des élémentsé des élémentsAccAccèès rapides rapide
Associe une clé unique et Associe une clé unique et une valeur. une valeur. AccAccèès rapides rapide
Structures de donnStructures de donnéées es hiérarchiques: les Arbreshiérarchiques: les Arbres
RacineRacine
B1B1 B2B2 B3B3
B7B7B6B6B5B5B4B4 F2F2F1F1
B8B8 B10B10B9B9 F4F4 F5F5F3F3
F7F7 F8F8F6F6 F10F10F9F9
Arbres: Arbres: SpSpécificationsécifications
Créer un arbreCréer un arbre
Ajout / retrait d’un noeudAjout / retrait d’un noeud
Détruire un arbreDétruire un arbre
Parcours pre-orderParcours pre-order
Parcours post-orderParcours post-order
Parcours in-orderParcours in-order
Arbres: Structure de donnArbres: Structure de donnéées es
TreeNode_tTreeNode_t
p_datap_data p_nextp_next
Data_tData_t
p_first_childp_first_childp_parentp_parent
Tree.hTree.h
typedef struct TreeNode_t {typedef struct TreeNode_t { struct TreeNode_t* p_parent_; struct TreeNode_t* p_parent_; struct TreeNode_t* p_first_child_;struct TreeNode_t* p_first_child_; Data_t* p_data_;Data_t* p_data_; struct TreeNode_t* p_next_;struct TreeNode_t* p_next_;} TreeNode_t;} TreeNode_t;
TreeNode_t* tree_add_node( TreeNode_t* tree_add_node( TreeNode_t* p_parent,TreeNode_t* p_parent,Data_t* p_dataData_t* p_data
););
Tree.hTree.h
TreeNode_t* tree_find_root( TreeNode_t* tree_find_root( TreeNode_t* p_parent,TreeNode_t* p_parent,Data_t* p_dataData_t* p_data
););
void tree_preorder( void tree_preorder( TreeNode_t* p_root,TreeNode_t* p_root,void(* do_it)( Data_t* )void(* do_it)( Data_t* )
););
void tree_postorder( void tree_postorder( TreeNode_t* p_root,TreeNode_t* p_root,void(* do_it)( Data_t* )void(* do_it)( Data_t* )
););
Tree.hTree.h
TreeNode_t* tree_delete_branch( TreeNode_t* tree_delete_branch( TreeNode_t* branchTreeNode_t* branch
););
void tree_inorder( void tree_inorder( TreeNode_t* p_root,TreeNode_t* p_root,void(* do_it)( Data_t* )void(* do_it)( Data_t* )
););
Arbres: parcours pre-orderArbres: parcours pre-order
11
5522
1010664433
998877
Pointeurs de fonctions...Pointeurs de fonctions...
Arbres: parcours post-orderArbres: parcours post-order
1010
9933
8 8 772211
665544
Arbres: parcours in-orderArbres: parcours in-order
44
9922
1010663311
887755
Structures de donnStructures de donnéées es complexes: Les Graphescomplexes: Les Graphes
N1N1 N2N2 N3N3
N9N9N7N7N6N6N5N5 N8N8N4N4
N10N10 N12N12N11N11 N14N14N13N13
N16N16N15N15 N18N18N17N17
Partie IVPartie IVAlgorithmes et complexitAlgorithmes et complexité :é :
exemple des trisexemple des tris
Exemple : Algorithmes de triExemple : Algorithmes de tri
Tri d’un tableau de taille n :Tri d’un tableau de taille n :n! possibilitésn! possibilités
Applications:Applications:bases de donnéesbases de donnéesgéométrie algorithmiquegéométrie algorithmique........
Fonctions: Fonctions:
de comparaison “<“de comparaison “<“
d’echanged’echange
Tri par remplacementTri par remplacement
Complexité en temps : o(n(n-1)) ~ o(nComplexité en temps : o(n(n-1)) ~ o(n22))
Mémoire: duplication du tableau.Mémoire: duplication du tableau.
BesoinsBesoins min_index, max_value, compmin_index, max_value, comp
tableaux tableaux entree, sortieentree, sortieint int max = max_value(entree)max = max_value(entree)PourPour i i dede 1 1 àà n n FaireFaire::
int int j <- j <- min_index(entree)min_index(entree)
sortie[i] <- entree[j]sortie[i] <- entree[j]entree[j] <- maxentree[j] <- max
FinPourFinPour
AlgoAlgo
Tri par permutationTri par permutation
Complexité en temps : o(n(n-1)/2) ~ o(nComplexité en temps : o(n(n-1)/2) ~ o(n22))
Mémoire: tableau non dupliquéMémoire: tableau non dupliqué
BesoinsBesoins min_index, swap, compmin_index, swap, comp
TableauTableau entrée entréePourPour i de 1 à n i de 1 à n FaireFaire::
int int j <- min_index(entree,i)j <- min_index(entree,i) SiSi j j ≠≠ i i FaireFaire
swapswap(entree[i],entree[j])(entree[i],entree[j]) FinSiFinSiFinPourFinPour
AlgoAlgo
Tri à bulles: PrincipeTri à bulles: Principe
BesoinsBesoins swap, compswap, comp
Echange de deux éléments adjacents du Echange de deux éléments adjacents du tableau.tableau.
Tri à bulles: AlgoTri à bulles: AlgoTableauTableau tab tabBooleen Booleen permute <- permute <- vraivraiint int i <- 0i <- 0Tant queTant que permute permute FaireFaire permute = permute = fauxfaux PourPour j de n-1 à i + 1 j de n-1 à i + 1 FaireFaire SiSi tab[j-1] > tab[j] tab[j-1] > tab[j] FaireFaire swapswap( tab[j-1], tab[j] )( tab[j-1], tab[j] ) permute = permute = vraivrai FinSiFinSi FinPourFinPour i++i++FinttqueFinttque
Tri à bulles: CommentairesTri à bulles: Commentaires
Complexité en temps : o(n(n-1)/2) ~ o(nComplexité en temps : o(n(n-1)/2) ~ o(n22))
Mémoire: tableau non dupliquéMémoire: tableau non dupliqué
Tri par sTri par séélection 4lection 4queque
On sépare le tableau en p ensembles.On sépare le tableau en p ensembles.On cherche un minimum pour chaque sous-On cherche un minimum pour chaque sous-ensembleensembleOn prend le minimum de ces minima.On prend le minimum de ces minima.On échange cet élément avec le premier On échange cet élément avec le premier élément élément etc.etc.
n ( p + n/p ) tests n ( p + n/p ) tests
o( n o( n n ) pour p = n ) pour p = nn
triétrié sous-table 1sous-table 1 sous-table psous-table p......
Tri par segmentation (quicksort)Tri par segmentation (quicksort)
On recherche une valeur pivot TOn recherche une valeur pivot Tjj..
On échange les valeurs de sorte que :On échange les valeurs de sorte que :• tout élément de [Ttout élément de [T00,T,Tj-1j-1] soit inférieur a T] soit inférieur a Tjj, ,
• tout élément de [Ttout élément de [Tj+1j+1, T, Tnn] soit supérieur a T] soit supérieur a Tjj
Méthode “diviser pour régner” :Méthode “diviser pour régner” :
On pivote récursivement sur On pivote récursivement sur [T[T00,T,Tj-1j-1] et [T] et [Tj+1j+1, T, Tnn].].
33 1 1 44 6 3 2 9 5 7 1 8 6 3 2 9 5 7 1 8 2233 1 2 1 2 66 3 2 9 5 7 3 2 9 5 7 11 8 4 8 433 1 2 1 3 2 9 5 7 6 8 4 1 2 1 3 2 9 5 7 6 8 42 1 2 1 3 2 1 2 1 3 33 9 5 7 6 8 4 9 5 7 6 8 4
22 1 2 1 3 1 2 1 31 1 2 1 1 2 22 3 31 1 21 1 22 32 3
33 9 5 7 6 8 4 9 5 7 6 8 433 99 5 7 6 5 7 6
8 48 44 5 7 6 8 4 5 7 6 8 99
77 6 8 6 86 6 77 8 8
55
994 4 5 7 6 85 7 6 84455 7 6 8 7 6 8
Tri par segmentation (quicksort)Tri par segmentation (quicksort)
seg (0,11)seg (0,11)
seg (0,4); seg (4,11)seg (0,4); seg (4,11)
seg (0,2); seg(3,4); seg(5,11)seg (0,2); seg(3,4); seg(5,11)
seg (0,11)seg (0,11)
seg (0,11)seg (0,11)
seg (0,11)seg (0,11)
seg (0,4); seg (5,11)seg (0,4); seg (5,11)
seg(5,10)seg(5,10)
seg(6,10)seg(6,10)
seg(7,10)seg(7,10)
seg(7,10)seg(7,10)
Complexité dans le cas favorable :Complexité dans le cas favorable :– loglog22(n) nombre de segmentations (n) nombre de segmentations
– 0 permutations0 permutations
– o(n logo(n log22 n) comparaisons n) comparaisons
Complexité dans le cas défavorable :Complexité dans le cas défavorable :– n nombre de segmentations n nombre de segmentations – o(no(n22) permutations) permutations– o(no(n22) comparaisons) comparaisons
Tri par segmentation (quicksort)Tri par segmentation (quicksort)
ConclusionConclusion
Algorithmique et structures de données sont Algorithmique et structures de données sont liées.liées.
Les exemples étudiés ont été implantés en Les exemples étudiés ont été implantés en C, mais le langage est plus un outil qu’une C, mais le langage est plus un outil qu’une fin en soi.fin en soi.
Bon courage pour vos projets !Bon courage pour vos projets !
Fonctionnement d’un programme et d’un Fonctionnement d’un programme et d’un ordinateurordinateur
Programmation en CProgrammation en C
ReferencesReferences
WebWeb Aho et al. Aho et al. Structures de donnees et Structures de donnees et
algorithmesalgorithmes, Addisson-Wesley / , Addisson-Wesley / InterEditions. 1989.InterEditions. 1989.
Aho et Ullman. Aho et Ullman. Concepts fondamentaux Concepts fondamentaux de l’informatiquede l’informatique, Dunod. 1993., Dunod. 1993.
Sedgewick. Sedgewick. Algorithmes en CAlgorithmes en C. . Addisson-Wesley / InterEditions. 1991.Addisson-Wesley / InterEditions. 1991.
Annexe: Pointeurs de fonctionAnnexe: Pointeurs de fonction
Déclaration Déclaration ::
type (* nom_de_fonction) ([arguments]);type (* nom_de_fonction) ([arguments]);
Utilisation :Utilisation :
(* nom_de_fonction) (arg1, arg2, arg3,...);(* nom_de_fonction) (arg1, arg2, arg3,...);
But : paramétrer des fonctions par d’autres But : paramétrer des fonctions par d’autres fonctions pour modifier leur actions.fonctions pour modifier leur actions.
Annexe: Pointeurs de fonctionAnnexe: Pointeurs de fonctionshort tab[10]short tab[10]
short carre( short v ) { return a * a; }short carre( short v ) { return a * a; }void imprimer( void imprimer(
int nb_elems, short (* function )( short ) int nb_elems, short (* function )( short ) ) {) {
for( i = 0; i < nb_elems; ++i ) {for( i = 0; i < nb_elems; ++i ) {printf( “%d ”, (* function) ( tab[i] ) );printf( “%d ”, (* function) ( tab[i] ) );
}}}}
int main() {int main() {for( i = 0; i < 10; i++ ) {for( i = 0; i < 10; i++ ) {
tab[i] = n;tab[i] = n;}}imprimer( 10, carre );imprimer( 10, carre );
}} Retour aux arbresRetour aux arbres