640 likes | 1.19k Views
Algorithmique. Cours ENSG 2A, Septembre 2002 Guillaume Caumon. http://www.ensg.inpl-nancy.fr/~caumon/Teach. Introduction. Un cours d’algorithmique a Géol… !???.
E N D
Algorithmique Cours ENSG 2A, Septembre 2002 Guillaume Caumon http://www.ensg.inpl-nancy.fr/~caumon/Teach
Introduction Un cours d’algorithmique a Géol… !??? Algorithme = suite d’actions que devra effectuer un automate pour arriver à partir d’un état initial, en un temps fini, à un résultat
Plan • Mémoire, pointeurs (1h) • Organisation d’un programme (1h) • Structures de données: listes, arbres, tables... (8h) • Algorithmique: exemple des tris (2h)
Les mémoires... • RAM (Random Access Memory): 32 / 64 Mo • Le disque dur: quelques Go • La mémoire virtuelle: temps d’accès 1000 fois plus long.
Mémoire et exécution Code Code objet du programme Données statiques Valeurs constantes Pile Piles d’appels de fonctions Tas Allocation dynamique de mémoire
Intérêts des pointeurs Gestion de l’espace mémoire en cours d’exécution Modifications de variables passées en paramètres de fonction Représentation de tableaux: accès direct et indexé Références croisées Fonctions virtuelles en programmation objet
Rappels sur les pointeurs int* a; a Déclaration d’un pointeur vers un entier
Rappels sur les pointeurs int* a; int* a = NULL; a Déclaration d’un pointeur vers un entier et initialisationà “NULL”
Rappels sur les pointeurs malloc(3*sizeof(int)); Allocation dynamique de place mémoire (pour 3 entiers)
a *a Rappels sur les pointeurs int* a = malloc(3*sizeof(int)); int* a = (int*)malloc(3*sizeof(int)); Allocation dynamique et assignement
*a Rappels sur les pointeurs free(a); a = NULL; a Désallocation dynamique
Rappels sur les pointeurs int* a = (int*)malloc(3*sizeof(int)); int* a = (int*)calloc(3, sizeof(int)); a = (int*)realloc(4*sizeof(int));
bin Fichiers de description (header) .dll .so .h .c .lib .o Fichiers d’implantation (source code) include a.out .exe Exécutable(s) src Programme ?? lib Librairies et fichiers objets Programme
Fichiers source = Instructions dans un langage de programmation Application, qui parle directement a l’ordinateur But du Jeu
Problèmes a résoudre Complexité, Coût de maintenance taille temps
Organisation et réutilisation… • Organisation du code : • En fonctions, structures, etc. • En fichiers • Réutilisation : • Du code (fichiers source) • Des fichiers binaires • Réutilisation d’un programme à l’autre
Programmes et librairies En C : Exécutable ↔ main() Pour la réutilisation, on utilise des bibliothèques (ou librairies) de fonctions : d’une description de chaque fonction (dans des fichier “.h” d’en-tête, ou header), et du code compilé correspondant (des “.lib” et “.dll” sous PC, des “.so” et “.a” sous UNIX)
.lib .c .h .so .o La Compilation : Résumé Fichiers d’en-tête C Code source C Préprocesseur Code pré-processé Librairies Compilateur Fichier(s) Objet Editeur de liens exécutable a.out .exe
Qualité d’un programme Architecture claire Réutilisabilité Structures de données + Algorithmes + Documentation + Tests de robustesse +
Partie III Introduction aux structures de données
“Comment Organiser au Mieux l’Information dans un Programme ?” Structures Tableaux Structures de données struct Data_t { int index_; char* value_; } Data_t; int tab[10]; Introduction Problème métaphysique:
Les tableaux Accès indexé (de 0 à n-1 pour un tableau de n éléments) Stockage compact Taille fixe, en général Réajustement de taille coûteux en temps Insertion d’élément onéreuse en temps.
Liste chaînée : Spécifications Créer une liste vide Ajouter un élément (début / fin / milieu) Retirer un élément (début / fin / milieu) Détruire une liste Trier les éléments d’une liste
Noeud Tête Liste chaînée : Structures Noeud Tête
Liste chaînée : Structures Node_t p_last p_data p_next nb_elements p_first List_t Data_t
Liste chaînée : Header typedef struct List_t { struct Node_t* p_first_; struct Node_t* p_last_; int nb_elements_; } List_t; typedef struct Node_t { struct Data_t* p_data_; struct Node_t* p_next_; } Node_t; typedef struct Data_t { ... } Data_t;
Liste chaînée : Header List_t* list_create( void ); int list_insert_item( List_t* list, Data_t* item ); int list_append_item( List_t* list, Data_t* item ); int list_insert_item_before( List_t* list, Data_t* to_insert, Data* list_item );
Liste chaînée : Header int list_destroy( List_t* list ); int list_empty( List_t* list ); Data_t* list_remove_head( List_t* list ); Data_t* list_remove_tail( List_t* list ); int list_remove_item( List_t* list Data_t* item ); int list_sort( List_t* list );
Liste chaînée : Utilisation Avant d’aller plus loin, vérifions si nos spécifications sont suffisantes... Pour cela, nous allons écrire un programme qui utilise les fonctions du fichier list.h, sans nous préoccuper de la façon dont elles sont implantées. But du programme: construire et trier une liste d’entiers par ordre croissant.
Liste chaînée : Implantation • Cf. code écrit au tableau; • pour résumer les principales règles à suivre: • Toujours tester la validité d’un pointeur avant de l’utiliser. • S’assurer de ne jamais perdre l’adresse d’une zone allouée dynamiquement. • Dans un programme, toute allocation parmallocoucalloc doit être suivie d’une désallocation parfree
void push(Data_t*) Data_t* pop(void) Liste chaînée : Spécialisations Pile, ou Tas (Stack): structure LIFO
Liste chaînée : Spécialisations File, ou queue : structure FIFO void push(Data_t*) Data_t* pop(void)
t = a · N2 t = a · 2N t = a · N t = a · logN Introduction à la complexité Annuaire avec noms et coordonnées temps t nombre d’abonnés N
Sets ou Bags et tables Stocker une seule fois le même élément dans le conteneur. Pas d’ordre Accès rapide Tables : Associent une clé a un élément dans le conteneur. Besoin de fonctions de hachage
Structures de données linéaires Taille fixe Accès direct Tableaux Taille variable Accès séquentiel Listes chaînées Unicité des éléments Accès rapide Sets, Bags Associe une clé unique et une valeur. Accès rapide Tables
B1 B2 B3 F1 B4 B5 B6 F2 B7 B8 B9 B10 F3 F4 F5 F6 F7 F8 F9 F10 Structures de données hiérarchiques: les Arbres Racine
Parcours pre-order Parcours post-order Parcours in-order Arbres: Spécifications Créer un arbre Ajout / retrait d’un noeud Détruire un arbre
Arbres: Structure de données TreeNode_t p_parent p_first_child p_data p_next Data_t
Tree.h typedef struct TreeNode_t { struct TreeNode_t* p_parent_; struct TreeNode_t* p_first_child_; Data_t* p_data_; struct TreeNode_t* p_next_; } TreeNode_t; TreeNode_t* tree_add_node( TreeNode_t* p_parent, Data_t* p_data );
Tree.h TreeNode_t* tree_find_root( TreeNode_t* p_parent, Data_t* p_data ); void tree_preorder( TreeNode_t* p_root, void(* do_it)( Data_t* ) ); void tree_postorder( TreeNode_t* p_root, void(* do_it)( Data_t* ) );
Tree.h void tree_inorder( TreeNode_t* p_root, void(* do_it)( Data_t* ) ); TreeNode_t* tree_delete_branch( TreeNode_t* branch );
Arbres: parcours pre-order 1 2 5 3 4 6 10 7 8 9 Pointeurs de fonctions...
Arbres: parcours post-order 10 3 9 1 2 7 8 4 5 6
Arbres: parcours in-order 4 2 9 1 3 6 10 5 7 8
Structures de données complexes: Les Graphes N1 N2 N3 N4 N5 N6 N7 N8 N9 N12 N10 N11 N13 N14 N15 N16 N17 N18
Partie IV Algorithmes et complexité : exemple des tris
Exemple : Algorithmes de tri Applications: bases de données géométrie algorithmique .... Tri d’un tableau de taille n : n! possibilités Fonctions: de comparaison “<“ d’echange
Besoins min_index, max_value, comp • Algo tableaux entree, sortie int max = max_value(entree) Pouri de 1 à n Faire: int j <- min_index(entree) sortie[i] <- entree[j] entree[j] <- max FinPour Tri par remplacement • Complexité en temps : o(n(n-1)) ~ o(n2) • Mémoire: duplication du tableau.