Académique Documents
Professionnel Documents
Culture Documents
Algorithmique
Structures de données
Florent Hivert
Mél : Florent.Hivert@lri.fr
Page personnelle : http://www.lri.fr/˜hivert
2 de 59
Structures
séquentielles : les
tableaux
Structures séquentielles : les tableaux 4 de 59
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 59
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 9 de 59
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 12 de 59
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.
En pratique . . .Python
En pratique . . .Java
Variables Dynamiques
et pointeurs
Variables Dynamiques et pointeurs 19 de 59
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 21 de 59
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 59
↑T ↑T
p ? allouer(p) p •
======⇒ T
?
Variables Dynamiques et pointeurs 24 de 59
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 26 de 59
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 59
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 59
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 structurées, enregistrements 31 de 59
Variables structurées,
enregistrements
Variables structurées, enregistrements 32 de 59
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 34 de 59
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.
Structures linéaires :
les listes chaînées
Structures linéaires : les listes chaînées 38 de 59
Idée
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 41 de 59
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 45 de 59
lst • a1 • a2 • an
à la fin
res • x •
plst • lst • a1 • a2 • an
à la fin
tmp • x •
lst • a1 • a2 • an
à la fin
res • a1 • a2 • an • x
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 50 de 59
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 52 de 59
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 53 de 59
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 54 de 59
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 •
Tables d’associations
Tables d’associations 58 de 59
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 59 de 59