Vous êtes sur la page 1sur 62

Algorithmique

Cours ENSG 2A, Septembre 2002 Guillaume Caumon

http://www.ensg.inpl-nancy.fr/~caumon/Teach

Introduction
Un cours dalgorithmique a Gol !???

Algorithme = suite dactions que devra effectuer un automate pour arriver partir dun tat initial, en un temps fini, un rsultat

Plan
Mmoire, pointeurs (1h) Organisation dun programme (1h) Structures de donnes: listes, arbres, tables... (8h) Algorithmique: exemple des tris (2h)

Partie I La mmoire

Les mmoires...

RAM (Random Access Memory): 32 / 64 Mo


Le disque dur: quelques Go

La mmoire virtuelle: temps daccs 1000 fois plus long.

Mmoire et excution
Code Donnes statiques Pile

Code objet du programme Valeurs constantes Piles dappels de fonctions

Tas

Allocation dynamique de mmoire

Intrts des pointeurs


Gestion de lespace mmoire en cours dexcution Modifications de variables passes en paramtres de fonction Reprsentation de tableaux: accs direct et index Rfrences croises Fonctions virtuelles en programmation objet

Rappels sur les pointeurs


int* a;
a

Dclaration dun pointeur vers un entier

Rappels sur les pointeurs


int* a;
a

int* a = NULL;

Dclaration dun pointeur vers un entier et initialisation NULL

Rappels sur les pointeurs


malloc(3*sizeof(int));

Allocation dynamique de place mmoire (pour 3 entiers)

Rappels sur les pointeurs


int* a = malloc(3*sizeof(int));
int* a = (int*)malloc(3*sizeof(int)); a
*a

Allocation dynamique et assignement

Rappels sur les pointeurs


free(a);
a
*a

a = NULL;

Dsallocation 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));

Partie II Survol darchitecture logicielle

Programme ??
bin a.out .exe

Excutable(s)
.so .lib .dll

lib
Programme include

.o

Librairies et fichiers objets


.h

Fichiers de description (header)


src .c

Fichiers dimplantation (source code)

But du Jeu

Fichiers source = Instructions dans un langage de programmation

Application, qui parle directement a lordinateur

Problmes a rsoudre
Complexit, Cot de maintenance

taille

temps

Organisation et rutilisation

Organisation du code :
En fonctions, structures, etc. En fichiers

Rutilisation

Du code (fichiers source) Des fichiers binaires


Rutilisation

dun programme lautre

Programmes et librairies
En C : Excutable main()
Pour la rutilisation, on utilise des bibliothques (ou librairies) de fonctions : dune description de chaque fonction (dans des fichier .h den-tte, ou header), et du code compil correspondant (des .lib et .dll sous PC, des .so et .a sous UNIX)

La Compilation : Rsum
Fichiers den-tte C
.h Prprocesseur

Code source C
.c

Code pr-process
Compilateur

Librairies
.lib .so

Fichier(s) Objet
.o

Editeur de liens

excutable
a.out .exe

Qualit dun programme


Architecture claire Rutilisabilit Structures de donnes + Algorithmes + Documentation + Tests de robustesse +

Partie III Introduction aux structures de donnes

Introduction
Problme mtaphysique: Comment Organiser au Mieux lInformation dans un Programme ?
Tableaux int tab[10]; Structures struct Data_t { int index_; char* value_; } Data_t;
Structures de donnes

Les tableaux

Accs index (de 0 n-1 pour un tableau de n lments) Stockage compact Taille fixe, en gnral Rajustement de taille coteux en temps Insertion dlment onreuse en temps.

Liste chane : Spcifications


Crer une liste vide
Ajouter un lment (dbut / fin / milieu) Retirer un lment (dbut / fin / milieu) Dtruire une liste Trier les lments dune liste

Liste chane : Structures


Noeud

Tte

Noeud

Tte

Liste chane : Structures


p_last nb_elements p_first

Node_t
p_data p_next

List_t

Data_t

Liste chane : 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 chane : 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 chane : 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 chane : Utilisation


Avant daller plus loin, vrifions si nos spcifications sont suffisantes...
Pour cela, nous allons crire un programme qui utilise les fonctions du fichier list.h, sans nous proccuper de la faon dont elles sont implantes.

But du programme: construire et trier une liste dentiers par ordre croissant.

Liste chane : Implantation


Cf. code crit au tableau; pour rsumer les principales rgles suivre: Toujours tester la validit dun pointeur avant de lutiliser.
Sassurer de ne jamais perdre ladresse dune zone alloue dynamiquement. Dans un programme, toute allocation par malloc ou calloc doit tre suivie dune dsallocation par free

Liste chane : Spcialisations


Pile, ou Tas (Stack): structure LIFO
void push(Data_t*) Data_t* pop(void)

Liste chane : Spcialisations


File, ou queue : structure FIFO

void push(Data_t*)

Data_t* pop(void)

Introduction la complexit
Annuaire avec noms et coordonnes
temps t t = a 2N t = a N2

t=aN

t = a logN

nombre dabonns N

Sets ou Bags et tables


Stocker une seule fois le mme lment dans le conteneur. Pas dordre

Accs rapide
Tables : Associent une cl a un lment dans le conteneur.

Besoin de fonctions de hachage

Structures de donnes linaires


Tableaux Listes chanes Sets, Bags Tables Taille fixe Accs direct Taille variable Accs squentiel Unicit des lments Accs rapide Associe une cl unique et une valeur. Accs rapide

Structures de donnes hirarchiques: les Arbres


Racine
B1 B2 B3

F1

B4
B8

B5
B9 B10

B6
F3

F2
F4

B7
F5

F6

F7

F8

F9

F10

Arbres: Spcifications
Crer un arbre Parcours pre-order Parcours post-order Parcours in-order Ajout / retrait dun noeud Dtruire un arbre

Arbres: Structure de donnes

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 3 4 7 6 8 5 10 9
Pointeurs de fonctions...

Arbres: parcours post-order


10 3 1 2 4 7 5 9 8 6

Arbres: parcours in-order


4 2 1 3 5 6 7 9 10 8

Structures de donnes complexes: Les Graphes

N1 N4 N5 N10 N15 N6 N11 N16

N2 N7 N12 N8 N13 N17

N3 N9 N14 N18

Partie IV Algorithmes et complexit : exemple des tris

Exemple : Algorithmes de tri


Applications: bases de donnes gomtrie algorithmique ....

Tri dun tableau de taille n : n! possibilits Fonctions:


de comparaison < dechange

Tri par remplacement


Besoins
Algo

min_index, max_value, comp


tableaux entree, sortie int max = max_value(entree) Pour i de 1 n Faire: int j <- min_index(entree) sortie[i] <- entree[j] entree[j] <- max FinPour

Complexit en temps : o(n(n-1)) ~ o(n2) Mmoire: duplication du tableau.

Tri par permutation


Besoins
Algo

min_index, swap, comp

Tableau entre Pour i de 1 n Faire: int j <- min_index(entree,i) Si j i Faire swap(entree[i],entree[j]) FinSi FinPour

Complexit en temps : o(n(n-1)/2) ~ o(n2) Mmoire: tableau non dupliqu

Tri bulles: Principe


Echange de deux lments adjacents du tableau.

Besoins

swap, comp

Tri bulles: Algo


Tableau tab Booleen permute <- vrai int i <- 0 Tant que permute Faire permute = faux Pour j de n-1 i + 1 Faire Si tab[j-1] > tab[j] Faire swap( tab[j-1], tab[j] ) permute = vrai FinSi FinPour i++ Finttque

Tri bulles: Commentaires

Complexit en temps : o(n(n-1)/2) ~ o(n2)


Mmoire: tableau non dupliqu

Tri par slection 4que


On spare le tableau en p ensembles. On cherche un minimum pour chaque sousensemble On prend le minimum de ces minima. On change cet lment avec le premier lment etc.
tri sous-table 1
... sous-table p

n ( p + n/p ) tests o( n n ) pour p = n

Tri par segmentation (quicksort)


Mthode diviser pour rgner : On recherche une valeur pivot Tj. On change les valeurs de sorte que : tout lment de [T0,Tj-1] soit infrieur a Tj, tout lment de [Tj+1, Tn] soit suprieur a Tj On pivote rcursivement sur [T0,Tj-1] et [Tj+1, Tn].

Tri par segmentation (quicksort)


seg (0,11) seg (0,11) seg (0,11) seg (0,11) seg (0,4); seg (4,11) seg (0,4); seg (5,11) seg (0,2); seg(3,4); seg(5,11) seg(5,10) seg(6,10) seg(7,10) seg(7,10)

314632957182 312632957184 312132957684 212133957684 212133957684 11223 3957684 11223 457689 45768 9 45768 5768 678

Tri par segmentation (quicksort)

Complexit dans le cas favorable :


log2(n) nombre de segmentations 0 permutations o(n log2 n) comparaisons

Complexit dans le cas dfavorable :


n nombre de segmentations o(n2) permutations o(n2) comparaisons

Conclusion
Fonctionnement dun programme et dun ordinateur

Programmation en C Algorithmique et structures de donnes sont lies.


Les exemples tudis ont t implants en C, mais le langage est plus un outil quune fin en soi.

Bon courage pour vos projets !

References
Web Aho et al. Structures de donnees et algorithmes, Addisson-Wesley / InterEditions. 1989. Aho et Ullman. Concepts fondamentaux de linformatique, Dunod. 1993. Sedgewick. Algorithmes en C. Addisson-Wesley / InterEditions. 1991.

Annexe: Pointeurs de fonction


But : paramtrer des fonctions par dautres fonctions pour modifier leur actions.

Dclaration : type (* nom_de_fonction) ([arguments]); Utilisation : (* nom_de_fonction) (arg1, arg2, arg3,...);

Annexe: Pointeurs de fonction


short tab[10]

short carre( short v ) { return a * a; } void imprimer( int nb_elems, short (* function )( short ) ) { for( i = 0; i < nb_elems; ++i ) { printf( %d , (* function) ( tab[i] ) ); } }
int main() { for( i = 0; i < 10; i++ ) { tab[i] = n; } imprimer( 10, carre ); }

Retour aux arbres