Documente Academic
Documente Profesional
Documente Cultură
Algorithmique
Structures de données
Florent Hivert
Mél : Florent.Hivert@lri.fr
Page personnelle : http://www.lri.fr/˜hivert
2 de 61
Structures
séquentielles : les
tableaux
Structures séquentielles : les tableaux 4 de 61
Définition
Un tableau est une structure de donnée T qui permet de stocker
un certain nombre d’éléments T [i] repérés par un index i. Les
tableaux vérifient généralement les propriétés suivantes :
tous les éléments ont le même type de base ;
le nombre d’éléments stockés est fixé ;
l’accès et la modification de l’élément numéro i est en temps
constant Θ(1), indépendant de i et du nombre d’éléments
dans le tableau.
Structures séquentielles : les tableaux 5 de 61
Tableau en C
Tableau en C
Tableau en C
Tableau en C
Tableau en Java
Opérations de base
Hypothèses :
tableau de taille max_taille alloué
éléments 0 ≤ i < taille ≤ max_taille initialisés
taille = max_taille
Comportements possibles :
Erreur (arrêt du programme, exception)
Ré-allocation du tableau avec recopie, coût : Θ(taille)
Structures séquentielles : les tableaux 8 de 61
taille = max_taille
Comportements possibles :
Erreur (arrêt du programme, exception)
Ré-allocation du tableau avec recopie, coût : Θ(taille)
Structures séquentielles : les tableaux 9 de 61
Ré-allocation (2)
k
X k(k + 1)
bi = b ∈ Θ(n2 )
2
i=1
Ré-allocation (2)
k
X k(k + 1)
bi = b ∈ Θ(n2 )
2
i=1
Quelques valeurs :
K 1.01 1.1 1.2 1.5 2 3 4 5 10
K
K −1 101 11 6 3 2 1.5 1.33 1.25 1.11
Interprétation :
Si l’on augmente la taille de 10% à chaque étape, chaque nombre
sera recopié en moyenne 11 fois.
Si l’on double la taille à chaque étape, chaque nombre sera en
moyenne recopié deux fois.
Structures séquentielles : les tableaux 11 de 61
Quelques valeurs :
K 1.01 1.1 1.2 1.5 2 3 4 5 10
K
K −1 101 11 6 3 2 1.5 1.33 1.25 1.11
Interprétation :
Si l’on augmente la taille de 10% à chaque étape, chaque nombre
sera recopié en moyenne 11 fois.
Si l’on double la taille à chaque étape, chaque nombre sera en
moyenne recopié deux fois.
Structures séquentielles : les tableaux 11 de 61
Quelques valeurs :
K 1.01 1.1 1.2 1.5 2 3 4 5 10
K
K −1 101 11 6 3 2 1.5 1.33 1.25 1.11
Interprétation :
Si l’on augmente la taille de 10% à chaque étape, chaque nombre
sera recopié en moyenne 11 fois.
Si l’on double la taille à chaque étape, chaque nombre sera en
moyenne recopié deux fois.
Structures séquentielles : les tableaux 12 de 61
Bilan
Compromis Espace/Temps
Retenir
C’est une situation très classique : dans de nombreux problèmes, il
est possible d’aller plus vite en utilisant plus de mémoire.
Compromis Espace/Temps
Retenir
C’est une situation très classique : dans de nombreux problèmes, il
est possible d’aller plus vite en utilisant plus de mémoire.
Compromis Espace/Temps
Retenir
C’est une situation très classique : dans de nombreux problèmes, il
est possible d’aller plus vite en utilisant plus de mémoire.
En pratique . . .Python
En pratique . . .Java
Variables Dynamiques
et pointeurs
Variables Dynamiques et pointeurs 19 de 61
Retenir
Une variable dynamique est anonyme :
(adresse, type, valeur) .
On y accède grâce à un pointeur.
adresse type
les quatre propriétés d’une variable usuelle nom valeur
x ↑T
schéma pour le pointeur p qui repère la VD p a
a T
d’adresse a, de type T et de valeur v
v
x ↑T
le lien dynamique entre le pointeur p et la VD p •
T
qu’il repère est illustré par une flèche
v
Variables Dynamiques et pointeurs 20 de 61
adresse type
les quatre propriétés d’une variable usuelle nom valeur
x ↑T
schéma pour le pointeur p qui repère la VD p a
a T
d’adresse a, de type T et de valeur v
v
x ↑T
le lien dynamique entre le pointeur p et la VD p •
T
qu’il repère est illustré par une flèche
v
Variables Dynamiques et pointeurs 20 de 61
adresse type
les quatre propriétés d’une variable usuelle nom valeur
x ↑T
schéma pour le pointeur p qui repère la VD p a
a T
d’adresse a, de type T et de valeur v
v
x ↑T
le lien dynamique entre le pointeur p et la VD p •
T
qu’il repère est illustré par une flèche
v
Variables Dynamiques et pointeurs 21 de 61
Retenir
Un pointeur p peut valoir NULL : il ne repère aucune VD.
↑T
schéma pour le pointeur p de type ↑ T qui ne p NULL
repère aucune VD
↑T
l’accès à aucune VD pour le pointeur p de p
type ↑ T est illustré par une croix
NULL est une valeur commune à tous les pointeurs, à ceux du type
↑ T comme à ceux des autres types.
Variables Dynamiques et pointeurs 21 de 61
Retenir
Un pointeur p peut valoir NULL : il ne repère aucune VD.
↑T
schéma pour le pointeur p de type ↑ T qui ne p NULL
repère aucune VD
↑T
l’accès à aucune VD pour le pointeur p de p
type ↑ T est illustré par une croix
NULL est une valeur commune à tous les pointeurs, à ceux du type
↑ T comme à ceux des autres types.
Variables Dynamiques et pointeurs 21 de 61
Retenir
Un pointeur p peut valoir NULL : il ne repère aucune VD.
↑T
schéma pour le pointeur p de type ↑ T qui ne p NULL
repère aucune VD
↑T
l’accès à aucune VD pour le pointeur p de p
type ↑ T est illustré par une croix
NULL est une valeur commune à tous les pointeurs, à ceux du type
↑ T comme à ceux des autres types.
Variables Dynamiques et pointeurs 21 de 61
Retenir
Un pointeur p peut valoir NULL : il ne repère aucune VD.
↑T
schéma pour le pointeur p de type ↑ T qui ne p NULL
repère aucune VD
↑T
l’accès à aucune VD pour le pointeur p de p
type ↑ T est illustré par une croix
NULL est une valeur commune à tous les pointeurs, à ceux du type
↑ T comme à ceux des autres types.
Variables Dynamiques et pointeurs 21 de 61
Retenir
Un pointeur p peut valoir NULL : il ne repère aucune VD.
↑T
schéma pour le pointeur p de type ↑ T qui ne p NULL
repère aucune VD
↑T
l’accès à aucune VD pour le pointeur p de p
type ↑ T est illustré par une croix
NULL est une valeur commune à tous les pointeurs, à ceux du type
↑ T comme à ceux des autres types.
Variables Dynamiques et pointeurs 22 de 61
↑T ↑T
p ? allouer(p) p •
======⇒ T
?
Variables Dynamiques et pointeurs 23 de 61
↑T ↑T
p ? allouer(p) p •
======⇒ T
?
Variables Dynamiques et pointeurs 24 de 61
Utilisations
Retenir
Si p repère une VD, cette variable est notée ∗p.
↑T
la VD de type T et de valeur v repérée par p p •
T
est notée ∗p
∗p v
Utilisations
Retenir
Si p repère une VD, cette variable est notée ∗p.
↑T
la VD de type T et de valeur v repérée par p p •
T
est notée ∗p
∗p v
Utilisations
Retenir
Si p repère une VD, cette variable est notée ∗p.
↑T
la VD de type T et de valeur v repérée par p p •
T
est notée ∗p
∗p v
↑T ↑T
p • désallouer(p) p ?
T ========⇒
v
Variables Dynamiques et pointeurs 25 de 61
↑T ↑T
p • désallouer(p) p ?
T ========⇒
v
Variables Dynamiques et pointeurs 25 de 61
↑T ↑T
p • désallouer(p) p ?
T ========⇒
v
Variables Dynamiques et pointeurs 25 de 61
↑T ↑T
p • désallouer(p) p ?
T ========⇒
v
Variables Dynamiques et pointeurs 26 de 61
Variable dynamique en C
Retenir
Déclaration d’un pointeur p de type ↑ T : T *p;
Allocation d’une VD pointée par p :
p = (T *) malloc(sizeof(T)) ;
note : en cas d’échec de l’allocation malloc retourne NULL.
Accès à la VD et à sa valeur :
*p = ...; ... = (*p) + 1;
Désallocation de la VD pointée par p :
free(p);
Variables Dynamiques et pointeurs 29 de 61
Les pointeurs en C
Retenir
Tout type de pointeur
supporte l’opération d’affectation =
peux être utilisé comme type de retour d’une fonction
Note : ajout d’un pointeur à un entier (en cas de variable
dynamique multiple ; tableau)
Pour deux pointeurs de même type :
test d’égalité ==, de différence !=
Note : comparaison <,<=,>,>= (en cas de variable dynamique
multiple ; tableau)
Variables Dynamiques et pointeurs 30 de 61
Le programme :
char *p, *q
p = (char *) malloc(sizeof(char));
*p = ’A’;
q = (char *) malloc(sizeof(char));
*q = ’B’;
*p = *q;
printf("%i, %i\n", p == q, *p == *q);
affiche :
0, 1
Variables Dynamiques et pointeurs 30 de 61
Le programme :
char *p, *q
p = (char *) malloc(sizeof(char));
*p = ’A’;
q = (char *) malloc(sizeof(char));
*q = ’B’;
*p = *q;
printf("%i, %i\n", p == q, *p == *q);
affiche :
0, 1
Variables Dynamiques et pointeurs 30 de 61
Le programme :
char *p, *q
p = (char *) malloc(sizeof(char));
*p = ’A’;
q = (char *) malloc(sizeof(char));
*q = ’B’;
*p = *q;
printf("%i, %i\n", p == q, *p == *q);
affiche :
0, 1
Variables Dynamiques et pointeurs 31 de 61
Retenir
variables = référence = pointeurs cachés sur var. dyn.
allocation avec la commande new
désallocation automatique si plus de références
pas accès à l’adresse, déréférencement automatique
objet Null ou None = pointeur invalide
pas d’appel de méthode sur Null
Variables structurées, enregistrements 32 de 61
Variables structurées,
enregistrements
Variables structurées, enregistrements 33 de 61
type structuré
Syntaxe
Déclaration de type structuré :
nom_de_type = structure:
nom_du_champ_1 : type_du_champ_1;
nom_du_champ_2 : type_du_champ_2;
...
v: nom_de_type;
Variables structurées, enregistrements 35 de 61
struct nom_de_struct {
nom_du_champ_1 : type_du_champ_1;
nom_du_champ_2 : type_du_champ_2;
...
};
struct nom_de_struct v;
struct s_date {
char nom_jour[9]; // lundi, mardi, ..., dimanche
int num_jour; // 1, 2, ..., 31
int mois; // 1, 2, ..., 12
int annee;
}
Retenir
Toute opération valide sur une variable de type type_du_champ_i
est valide sur v.nom_du_champ_i.
Retenir
Accès à un champ en temps constant : O(1).
Retenir
Du point de vue de la complexité, on peut voir les objets comme
des structures avec une syntaxe particulière pour l’appel de fonction
et des mécanismes de contrôle de type et de réutilisation de code
amélioré (Héritage)
Variables structurées, enregistrements 38 de 61
Retenir
Accès à un champ en temps constant : O(1).
Retenir
Du point de vue de la complexité, on peut voir les objets comme
des structures avec une syntaxe particulière pour l’appel de fonction
et des mécanismes de contrôle de type et de réutilisation de code
amélioré (Héritage)
Structures linéaires : les listes chaînées 39 de 61
Structures linéaires :
les listes chaînées
Structures linéaires : les listes chaînées 40 de 61
Idée
Chaînages dynamiques
Chaînages dynamiques
Chaînages dynamiques
Chaînages dynamiques
Retenir
Une liste chaînée est obtenue à partir du type cellule définie par
cellule = structure:
val: element
next : ^cellule
liste = ^cellule
En C :
struct s_cell
{
element val;
struct s_cell * next;
};
typedef struct s_cell cell; // Cellule
typedef struct s_cell *list; // Liste Chaînée
Structures linéaires : les listes chaînées 42 de 61
Retenir
Une liste chaînée est obtenue à partir du type cellule définie par
cellule = structure:
val: element
next : ^cellule
liste = ^cellule
En C :
struct s_cell
{
element val;
struct s_cell * next;
};
typedef struct s_cell cell; // Cellule
typedef struct s_cell *list; // Liste Chaînée
Structures linéaires : les listes chaînées 43 de 61
Pointeur et structure
Syntaxe
Accès aux données d’une liste chaînée :
VD pointée par lst : *lst
champ val de cell : cell.val
champ val de la VD pointée par lst :
Les notions sur les suites finies passent aux listes dynamiques
qu’elles implantent : longueur, concaténation, position...
Calcul itératif :
int longueur(list lst) {
int k = 0;
list q = lst;
while (q != NULL) {
q = q->next; k++;
}
return k;
}
Calcul récursif :
int longueur(list lst) {
if (lst == NULL) return 0;
else return 1 + longueur(lst->next);
}
Structures linéaires : les listes chaînées 46 de 61
Les notions sur les suites finies passent aux listes dynamiques
qu’elles implantent : longueur, concaténation, position...
Calcul itératif :
int longueur(list lst) {
int k = 0;
list q = lst;
while (q != NULL) {
q = q->next; k++;
}
return k;
}
Calcul récursif :
int longueur(list lst) {
if (lst == NULL) return 0;
else return 1 + longueur(lst->next);
}
Structures linéaires : les listes chaînées 46 de 61
Les notions sur les suites finies passent aux listes dynamiques
qu’elles implantent : longueur, concaténation, position...
Calcul itératif :
int longueur(list lst) {
int k = 0;
list q = lst;
while (q != NULL) {
q = q->next; k++;
}
return k;
}
Calcul récursif :
int longueur(list lst) {
if (lst == NULL) return 0;
else return 1 + longueur(lst->next);
}
Structures linéaires : les listes chaînées 47 de 61
lst • a1 • a2 • an
à la fin
res • x •
lst • a1 • a2 • an
à la fin
res • x •
lst • a1 • a2 • an
à la fin
res • x •
plst • lst • a1 • a2 • an
à la fin
tmp • x •
plst • lst • a1 • a2 • an
à la fin
tmp • x •
plst • lst • a1 • a2 • an
à la fin
tmp • x •
plst • lst • a1 • a2 • an
à la fin
tmp • x •
lst • a1 • a2 • an
à la fin
res • a1 • a2 • an • x
lst • a1 • a2 • an
à la fin
res • a1 • a2 • an • x
plst • lst • a1 • a2 • an • x
à la fin cur •
tmp •
plst • lst • a1 • a2 • an • x
à la fin cur •
tmp •
le pointeur p repère la
lst • a1 • a2 • an
LDSC avec une fausse
tête qui implante la suite
? •
ha1 , a2 , . . . , an i
Intérêts :
en mode avec mutation ;
évite d’avoir à distinguer les cas de l’élément de tête ou de la
liste vide dans les opérations d’insertion et de suppression.
Structures linéaires : les listes chaînées 51 de 61
le pointeur p repère la
lst • a1 • a2 • an
LDSC avec une fausse
tête qui implante la suite
? •
ha1 , a2 , . . . , an i
Intérêts :
en mode avec mutation ;
évite d’avoir à distinguer les cas de l’élément de tête ou de la
liste vide dans les opérations d’insertion et de suppression.
Structures linéaires : les listes chaînées 52 de 61
pointeurs repérant
respectivement la tête et la
•• a1 • a2 • an
queue de la LDSC qui implante
la suite ha1 , a2 , . . . , an i
Intérêts :
en mode avec mutation ;
ajout en queue sans parcours de la LDSC ;
concaténation sans parcours des LDSC.
pointeurs repérant
respectivement la tête et la
•• a1 • a2 • an
queue de la LDSC qui implante
la suite ha1 , a2 , . . . , an i
Intérêts :
en mode avec mutation ;
ajout en queue sans parcours de la LDSC ;
concaténation sans parcours des LDSC.
pointeurs repérant
respectivement la tête et la
•• a1 • a2 • an
queue de la LDSC qui implante
la suite ha1 , a2 , . . . , an i
Intérêts :
en mode avec mutation ;
ajout en queue sans parcours de la LDSC ;
concaténation sans parcours des LDSC.
a1 •
• an •
Intérêts :
en mode avec mutation ;
ajout en queue et suppression en tête sans parcours de la
LDSC ;
concaténation sans parcours des LDSC.
Structures linéaires : les listes chaînées 53 de 61
a1 •
• an •
Intérêts :
en mode avec mutation ;
ajout en queue et suppression en tête sans parcours de la
LDSC ;
concaténation sans parcours des LDSC.
Structures linéaires : les listes chaînées 54 de 61
pointeurs repérant
respectivement la
tête et la queue de a1 •
•• • a2 • • an
la LDDC qui
implante la suite
ha1 , a2 , . . . , an i
Intérêts :
en mode avec mutation ;
marches avant et arrière ;
ajout en queue et suppression en tête sans parcours de la
LDDC ;
concaténation sans parcours des LDDC.
Structures linéaires : les listes chaînées 54 de 61
pointeurs repérant
respectivement la
tête et la queue de a1 •
•• • a2 • • an
la LDDC qui
implante la suite
ha1 , a2 , . . . , an i
Intérêts :
en mode avec mutation ;
marches avant et arrière ;
ajout en queue et suppression en tête sans parcours de la
LDDC ;
concaténation sans parcours des LDDC.
Structures linéaires : les listes chaînées 55 de 61
struct s_cell
{
element val;
struct s_cell * next;
struct s_cell * prev;
};
struct s_lddc
{
struct s_cell * first;
struct s_cell * last;
};
Structures linéaires : les listes chaînées 56 de 61
Applications
Applications
Liste des • a • • b • • c •
candidats ;
sélection de b choix •
choix->next->prev = choix->prev;
choix->prev->next = choix->next;
Suppression de • a • • b • • c •
b de la liste
choix •
Liste des • a • • b • • c •
candidats ;
sélection de b choix •
choix->next->prev = choix->prev;
choix->prev->next = choix->next;
Suppression de • a • • b • • c •
b de la liste
choix •
Tables d’associations
Tables d’associations 60 de 61
Tables d’associations
Définition (table)
Une table est une fonction d’un ensemble d’entrées dans un
ensemble de valeurs.
C’est un objet informatique : il s’agit de ranger une information
(valeur) associée à chaque index (entrée), de retrouver l’information
à partir de l’index, de la modifier ou de supprimer couple
index-information.
Tables d’associations 61 de 61