Telechargé par Mohamed Amine Ouassil

APR2 10 Listes files et piles

publicité
Analyse et programmation 2
Listes, files et piles
Thèmes abordés
• Introduction à l’analyse de la complexité algorithmique
• TDA Liste
– Implémentation sous forme de tableau.
– Opérations élémentaires. Analyse de la complexité.
• TDA Liste chaînée
– Introduction aux structures de données récursives.
– Liste simplement chaînée, opérations et complexité.
– Liste doublement chaînée, opérations et complexité.
•
A t
Autres
TDA
– Files, piles
– Aperçu des arbres et des graphes.
• Quelques algorithmes de tri
– Analyse de complexité
Analyse et programmation 2 - Listes, files et piles
1
1
Introduction à la complexité algorithmique
Analyse des temps d’exécution des algorithmes
• Le temps d’exécution d’un algorithme dépend
–
–
–
–
De l’organisation de traitements dans l’algorithme.
l’algorithme
Des données entrante dans l’algorithme.
De la qualité du code généré par le compilateur.
De la rapidité d’exécution du microprocesseur.
figé
variable
figé
figé
• Nécessité de pouvoir prédire le pire temps d’exécution
– Pour pouvoir garantir une réactivité acceptable des applications.
Analyse et programmation 2 - Listes, files et piles
2
Introduction à la complexité algorithmique
Analyse des temps d’exécution des algorithmes
• On considère un algorithme
– Recevant
Rece ant en entrée une
ne donnée dépendant d’
d’un
n facte
facteurr N
• Peut être une valeur utilisée pour un calcul : factorielle(N).
• Peut être la taille d’une donnée : tableau ou liste de taille N.
– Temps d’exécution de cet algorithme: donné par une fonction
• T(N)
• Complexité algorithmique
– On dit que l’algorithme
l algorithme est de complexité O(f(n)) s’il
s il existe
• Une fonction f(n)
• deux constantes c et n0
– telles que
• Pour tout n > n0, T(n) < c . f(n)
Analyse et programmation 2 - Listes, files et piles
3
2
Introduction à la complexité algorithmique
Analyse des temps d’exécution des programmes – exemples simples
int produit(int a, int b)
{
return a * b;
}
int factorielle(int n)
{
int i, resultat;
resultat = 1;
for (i = 2; i <= n; i++)
resultat = produit(resultat, i);
return resultat;
O(1)
O(n)
}
double developpement_limite_exponentielle(double x, int n)
{
double resultat = 0.0;
O(n2)
int i;
for (i = 0; i <= n; i++)
resultat = resultat + pow(x, i) / factorielle(i);
return resultat;
}
Analyse et programmation 2 - Listes, files et piles
4
Liste d’imprimantes
TDA Liste
Introduction – Les applications
Liste de fichiers
Liste de périphériques
Liste d’utilisateurs
Analyse et programmation 2 - Listes, files et piles
5
3
TDA Liste
Introduction – Les applications
Liste de livres
Analyse et programmation 2 - Listes, files et piles
6
TDA Liste
Introduction – Les applications
• Ce support de cours
– Liste de diapositives
diapositi es
• Chaque diapositive
– Liste de symboles
– Liste d’animations
• Un polygone
– Liste de segments
• Une feuille de calcul
– Liste de cellules
• Un document de traitement de texte
– Liste de caractères
Analyse et programmation 2 - Listes, files et piles
7
4
TDA Liste
Définition
• Une liste est
– Une collection d’éléments de même type.
t pe
– Par opposition à un tableau, le nombre d’éléments est variable.
– Les éléments peuvent être
• Des données de type simple : int, double, …
• Des données composées : struct, tableau.
• Illustration
– Exemples du cours basés sur une liste de réels.
Analyse et programmation 2 - Listes, files et piles
8
TDA Liste – représentation sous forme de tableau
Les opérations
• Initialiseurs
– Initialiser la liste.
liste
• Sélecteurs
– Taille, Accès à un élément, Vide, Pleine.
• Modificateurs
– Ajouter en fin, Insérer, Supprimer, Vider.
• Itérateurs
– Accéder aux éléments en séquence.
Analyse et programmation 2 - Listes, files et piles
9
5
TDA Liste - tableau
Représentation interne sous forme de tableau à taille fixe
• Principe
– Utilisation d’
d’un
n tablea
tableau à taille fi
fixe,
e ssurdimensionné
rdimensionné
– Mémorisation du nombre d’éléments effectif dans une variable.
• Déclaration du type de données
#define CAPACITE_LISTE_TABLEAU 100
typedef double ELEMENT;
Rappel – TDA :
Une application n’accède jamais
directement aux champs !
typedef struct
{
int nombre_elements;
ELEMENT elements[CAPACITE_LISTE_TABLEAU];
} LISTE_TABLEAU;
Analyse et programmation 2 - Listes, files et piles
10
TDA Liste – représentation sous forme de tableau
Les opérations
#define INDICE_INVALIDE -1
void liste_initialiser(LISTE_TABLEAU* liste);
int liste_nombre_elements(LISTE_TABLEAU* liste);
int liste_pleine(LISTE_TABLEAU* liste);
int liste_vide(LISTE_TABLEAU* liste);
ELEMENT liste_element(LISTE_TABLEAU* liste, int indice);
int liste_position_element(LISTE_TABLEAU* liste, ELEMENT e);
// Resultat : indice de l'élément, ou INDICE_INVALIDE en cas d'échec
int liste_ajouter(LISTE_TABLEAU* liste, ELEMENT e);
int liste_inserer(LISTE_TABLEAU* liste, int indice, ELEMENT e);
int liste_supprimer(LISTE_TABLEAU* liste, int indice);
void liste_vider(LISTE_TABLEAU* liste);
Analyse et programmation 2 - Listes, files et piles
11
6
TDA Liste - tableau
Initialisation
• But
– Préparer la liste à recevoir
rece oir des éléments
éléments.
– Initialement, la liste sera donc vide.
• Implémentation
void liste_initialiser(LISTE_TABLEAU* liste)
{
liste->nombre_elements = 0;
}
• Complexité O(1)
Analyse et programmation 2 - Listes, files et piles
12
TDA Liste - tableau
Accès au nombre d’éléments
int liste_nombre_elements(LISTE_TABLEAU* liste)
{
return liste->nombre_elements;
}
int liste_pleine(LISTE_TABLEAU* liste)
{
return liste_nombre_elements(liste) ==
CAPACITE_LISTE_TABLEAU;
}
Réutilisation d’une opération du TDA
int liste_vide(LISTE_TABLEAU* liste)
{
return liste_nombre_elements(liste) == 0;
}
Analyse et programmation 2 - Listes, files et piles
13
7
TDA Liste - tableau
Accès à un élément par position
ELEMENT liste_element(LISTE_TABLEAU* liste, int indice)
{
if (indice >= 0 && indice < liste->nombre_elements)
return liste->elements[indice];
else
{
printf("Erreur d'indice\n");
return 0;
}
Contrôles de validité du TDA
}
Analyse et programmation 2 - Listes, files et piles
14
TDA Liste - tableau
Recherche de la position d’un élément
int liste_position_element(LISTE_TABLEAU* liste, ELEMENT e)
{
int i;
i
int indice;
indice = INDICE_INVALIDE;
for (i = 0; i < liste->nombre_elements; i++)
if (liste->elements[i] == e)
{
indice = i;
break;
}
return indice;
}
Complexité ?
Analyse et programmation 2 - Listes, files et piles
15
8
TDA Liste - tableau
Ajout d’un élément à la fin
int liste_ajouter(LISTE_TABLEAU* liste, ELEMENT e)
{
int indice;
Contrôle de validité du TDA
if (!liste_pleine(liste))
{
indice = liste->nombre_elements;
liste->elements[indice] = e;
liste->nombre_elements++;
}
else
indice = INDICE_INVALIDE;
return indice;
}
Complexité ?
Analyse et programmation 2 - Listes, files et piles
16
TDA Liste - tableau
Insertion d’un élément à une position donnée
0
1
2
3
4
5
6
7
8
9
10
11
12
13
7
8
9
10
11
12
13
7
8
9
10
11
12
13
2.0 1.5 7.3 8.1 4.5 6.3
liste_inserer(liste, 2, 9.9);
0
1ère étape
1
2
3
5
6
2.0 1.5 7.3 7.3
8.1 8.1
4.5 4.5
6.3 6.3
4
2ème étape
4
0
1
2
3
3
2
4
1
5
6
2.0 1.5 9.9
7.3 7.3
8.1 8.1
4.5 4.5
6.3 6.3
5
9.9
Analyse et programmation 2 - Listes, files et piles
17
9
TDA Liste - tableau
Insertion d’un élément à une position donnée
int liste_inserer(LISTE_TABLEAU* liste, int indice, ELEMENT e)
{
int i;
int resultat;
if (!liste_pleine(liste))
if (indice >= 0 && indice <= liste->nombre_elements)
{
for (i = liste->nombre_elements; i > indice; i--)
liste->elements[i] = liste->elements[i - 1];
liste->nombre_elements++;
liste->elements[indice] = e;
resultat = indice;
}
else
resultat = INDICE_INVALIDE;
else
resultat = INDICE_INVALIDE;
Complexité ?
return resultat;
}
Analyse et programmation 2 - Listes, files et piles
18
TDA Liste - tableau
Suppression d’un élément à une position donnée
0
1
2
3
4
5
6
7
8
9
10
11
12
13
7
8
9
10
11
12
13
7
8
9
10
11
12
13
2.0 1.5 9.9 7.3 8.1 4.5 6.3
liste_supprimer(liste, 1);
0
1ère étape
1
2
4
5
6
2.0 9.9
1.5 7.3
9.9 8.1
7.3 4.5
8.1 6.3
4.5 6.3
1
2ème étape
3
0
1
2
2
3
3
4
4
5
5
6
2.0 9.9 7.3 8.1 4.5 6.3 6.3
Analyse et programmation 2 - Listes, files et piles
19
10
TDA Liste - tableau
Suppression d’un élément
int liste_supprimer(LISTE_TABLEAU* liste, int indice)
{
int i;
i
int resultat;
if (indice >= 0 && indice < liste->nombre_elements)
{
for (i = indice + 1; i < liste->nombre_elements; i++)
liste->elements[i - 1] = liste->elements[i];
liste->nombre_elements--;
resultat = indice;
}
else
resultat = INDICE_INVALIDE;
return resultat;
}
Complexité ?
Analyse et programmation 2 - Listes, files et piles
20
TDA Liste - tableau
Suppression de tous les éléments
0
1
2
3
4
5
6
7
8
9
10
11
12
13
7
8
9
10
11
12
13
2 0 1.5
2.0
1 5 9.9
9 9 7.3
7 3 8.1
8 1 4.5
4 5 6.3
63
0
1
2
3
4
5
6
void liste_vider(LISTE_TABLEAU* liste)
{
liste->nombre_elements = 0;
}
Analyse et programmation 2 - Listes, files et piles
21
11
TDA Liste - tableau
Parcours de la liste en avant / en arrière
• Le parcours est facile à implémenter et efficace.
• Exemple
void afficher_liste(LISTE_TABLEAU * liste)
{
int i, nombre_elements;
nombre_elements = liste_nombre_elements(liste);
printf("{");
for (i = 0; i < nombre_elements; i++)
{
if (i > 0)
printf(", ");
printf("%lg", liste_element(liste, i));
}
printf("}");
}
Analyse et programmation 2 - Listes, files et piles
22
TDA Liste - tableau
Analyse
• Avantages
– Accès rapide à to
toutt élément
élément.
– Simplicité.
• Inconvénients
– Opérations d’insertion et de suppression lentes :
• Recopie de nombreux éléments.
• Peu efficace pour des listes volumineuses.
– Besoin de sur
sur-dimensionner
dimensionner les tableaux
• Occupation mémoire pas optimisée.
– Aucune flexibilité sur le nombre maximum d’éléments
• Lorsque le maximum prévu est atteint, plus de possibilité d’ajouter
ne serait ce qu’un seul élément.
Analyse et programmation 2 - Listes, files et piles
23
12
TDA Liste - tableau
Représentation interne sous forme de tableau dynamique
• Pour pallier aux inconvénients du tableau fixe
– Possibilité d’allo
d’allouer
er d
dynamiquement
namiq ement un
n tablea
tableau.
– Réallocation pour suivre la croissance de la liste.
• Levée des problèmes
– De surconsommation de mémoire.
– De manque de flexibilité.
• Maintien des problèmes d’efficacité
– Opérations
é
d’insertion et de suppression.
Analyse et programmation 2 - Listes, files et piles
24
TDA Liste - tableau
Mise en œuvre avec un tableau dynamique
• Déclaration de la structure de données
typedef struct
{
int capacite;
int nombre_elements;
ELEMENT * elements; // tableau alloué dynamiquement
} LISTE_TABLEAU;
Analyse et programmation 2 - Listes, files et piles
25
13
TDA Liste – tableau
Mise en œuvre avec un tableau dynamique
• Fonction privée pour l’allocation de la mémoire
static int liste_etablir_capacite(LISTE_TABLEAU* liste, int capacite_desiree)
{
const int PAS_INCREMENT_CAPACITE = 10;
int succes;
int capacite;
ELEMENT * nouveau_tableau;
capacite = (1 + (capacite_desiree - 1) / PAS_INCREMENT_CAPACITE) *PAS_INCREMENT_CAPACITE;
if (liste->capacite != capacite)
{
if (liste->elements == NULL)
{
liste->elements = (ELEMENT *)malloc(sizeof(ELEMENT) * capacite);
succes = liste->elements != NULL;
}
else
{
nouveau tableau = realloc(liste
nouveau_tableau
realloc(liste->elements,
>elements sizeof(ELEMENT) * capacite);
succes = nouveau_tableau != NULL;
if (succes)
liste->elements = nouveau_tableau;
}
if (succes)
liste->capacite = capacite;
}
else
succes = 1;
return succes;
}
Analyse et programmation 2 - Listes, files et piles
26
TDA Liste - tableau
Mise en œuvre avec un tableau dynamique
• Initialisation
void liste_initialiser(LISTE_TABLEAU*
liste initialiser(LISTE TABLEAU* liste)
{
liste->nombre_elements = 0;
liste->capacite = 0;
liste->elements = NULL;
liste_etablir_capacite(liste, 0);
}
Analyse et programmation 2 - Listes, files et piles
27
14
TDA Liste - tableau
Mise en œuvre avec un tableau dynamique
• Ajout
int liste
liste_ajouter(LISTE_TABLEAU*
ajouter(LISTE TABLEAU* liste
liste, ELEMENT e)
{
int indice;
if (liste_etablir_capacite(liste, liste->nombre_elements + 1))
{
indice = liste->nombre_elements;
liste->elements[indice] = e;
liste->nombre_elements++;
}
else
indice = INDICE_INVALIDE;
return indice;
}
Analyse et programmation 2 - Listes, files et piles
28
TDA Liste - tableau
Conclusions
• L’utilisation d’un TDA pour une liste est judicieux
– Le passage d’
d’une
ne liste à taille fi
fixe
e vers
ers une
ne liste à taille variable
ariable
se fait sans aucun changement de spécification sur les opérations
du TDA.
– Il faudrait cependant ajouter une opération :
• liste_finaliser
• Pour libérer la mémoire allouée.
• Dans la pratique
– Les listes basées sur des tableaux à taille variables sont très
largement utilisées : C++, Java, C#.
– En particulier pour mémoriser des variables de petite taille.
– Souvent le cas en programmation orientée objet
• Listes de pointeurs sur des objets.
Analyse et programmation 2 - Listes, files et piles
29
15
Analyse et programmation 2 - Listes, files et piles
30
Variantes des listes : les piles
Introduction
• Rappel du fonctionnement d’une pile
– Opérations : empiler,
empiler dépiler
– Le dernier entré est le premier sorti
• Last In, First Out : LIFO
Analyse et programmation 2 - Listes, files et piles
31
16
Variantes des listes : les piles
Applications pratiques
• Dans la pratique
– Logiciels de bureautique
• La fonction « annuler »
• La première opération
annulée est la dernière
effectuée
– Navigateur Web
• Fonction « précédent »
• La première page
ouverte est la dernière
lue.
• Utilisées pour de
nombreux algorithmes
– Ex : parcours
d’arborescence.
Analyse et programmation 2 - Listes, files et piles
32
Variantes des listes : les piles
Les opérations
• Initialiseur
• Modificateurs
M difi t
– Empiler (PUSH) : ajoute un élément sur la pile.
– Dépiler (POP) : enlève l’élément au sommet de la pile.
• Sélecteurs
– Est vide
– Nombre d’éléments.
– Elément
é
situé
é au sommet.
Analyse et programmation 2 - Listes, files et piles
33
17
Variantes des listes : les piles
Implémentation basée sur la liste tableau
#ifndef __PILE_H_
#define __PILE_H_
#include "ListeTableauDynamique.h"
typedef struct
{
LISTE_TABLEAU liste;
} PILE;
void pile_initialiser(PILE * p);
void
o d p
pile
e_e
empiler(PILE
p e (
* p, ELEMENT e);
ELEMENT pile_depiler(PILE * p);
int pile_vide(PILE * p);
int pile_nombre_elements(PILE * p);
ELEMENT pile_sommet(PILE * p);
#endif
Analyse et programmation 2 - Listes, files et piles
34
Variantes des listes : les piles
Implémentation basée sur la liste tableau
void pile_initialiser(PILE * p)
{
liste initialiser(&p >liste)
liste_initialiser(&p->liste);
}
int pile_vide(PILE * p)
{
return pile_nombre_elements(p) == 0;
}
int pile_nombre_elements(PILE * p)
{
return liste_nombre_elements(&p->liste);
}
void pile_empiler(PILE * p, ELEMENT e)
{
liste_ajouter(&p->liste, e);
}
Analyse et programmation 2 - Listes, files et piles
35
18
Variantes des listes : les piles
Implémentation basée sur la liste tableau
ELEMENT pile_sommet(PILE * p)
{
int indice_sommet;
indice sommet
indice_sommet = liste_nombre_elements(&p->liste) - 1;
if (indice_sommet >= 0)
return liste_element(&p->liste, indice_sommet);
else
{
printf("Erreur");
return 0;
}
}
Analyse et programmation 2 - Listes, files et piles
36
Variantes des listes : les piles
Implémentation basée sur la liste tableau
ELEMENT pile_depiler(PILE * p)
{
ELEMENT res
resultat;
ltat
int indice_sommet;
indice_sommet = liste_nombre_elements(&p->liste) - 1;
resultat = pile_sommet(p);
liste_supprimer(&p->liste, indice_sommet);
return resultat;
}
Analyse et programmation 2 - Listes, files et piles
37
19
Variantes des listes : les piles
Implémentation basée sur la liste tableau - Analyse
• Difficulté de programmation ?
• Efficacité d’exécution ?
– Avec des tableaux dynamiques :
• Lenteur lors du redimensionnement, surtout avec les grands tableaux.
– Avec des tableaux fixes
• Capacité limitée de la pile
• Sur-occupation de mémoire.
Analyse et programmation 2 - Listes, files et piles
38
Variantes des listes : les files
Introduction
• Rappel du fonctionnement d’une pile
– Opérations : enfiler,
enfiler défiler
– Le premier entré est le premier sorti
• First In, First Out : FIFO
Analyse et programmation 2 - Listes, files et piles
39
20
Variantes des listes : les files
Applications pratiques
• Ordonnancement du traitement des achats d’un magasin en ligne.
• Gestion des ordres reçus par un système embarqué.
embarqué
• File d’attente d’une imprimante.
• Traitement de signal : implémentation d’un retard numérique.
Analyse et programmation 2 - Listes, files et piles
40
Variantes des listes : les files
Les opérations
• Initialiseur
• Modificateurs
M difi t
– Enfiler (PUSH) : ajoute un élément à l’entrée de la file.
– Défiler (POP) : enlève un élément à la sortie de la file.
• Sélecteurs
– Est vide
– Nombre d’éléments.
Analyse et programmation 2 - Listes, files et piles
41
21
Variantes des listes : les files
Implémentation basée sur la liste tableau
#ifndef __FILE_H_
#define __FILE_H_
#include "ListeTableauDynamique.h"
typedef struct
{
LISTE_TABLEAU liste;
} FILE_TABLEAU;
void file_initialiser(FILE_TABLEAU * f);
void
o d file
e_e
enfiler(FILE
e (
_TABLEAU
U * f,
, ELEMENT e);
ELEMENT file_defiler(FILE_TABLEAU * f);
int file_vide(FILE_TABLEAU * f);
int file_nombre_elements(FILE_TABLEAU * f);
#endif
Analyse et programmation 2 - Listes, files et piles
42
Variantes des listes : les files
Implémentation basée sur la liste tableau
void file_initialiser(FILE_TABLEAU * f)
{
liste initialiser(&f >liste)
liste_initialiser(&f->liste);
}
int file_vide(FILE_TABLEAU * f)
{
return file_nombre_elements(f) == 0;
}
int file_nombre_elements(FILE_TABLEAU * f)
{
return liste_nombre_elements(&f->liste);
}
Analyse et programmation 2 - Listes, files et piles
43
22
Variantes des listes : les files
Implémentation basée sur la liste tableau
void file_enfiler(FILE_TABLEAU * f, ELEMENT e)
{
liste ajo ter(&f >liste e)
liste_ajouter(&f->liste,
e);
}
ELEMENT file_defiler(FILE_TABLEAU * f)
{
ELEMENT resultat;
resultat = liste_element(&f->liste, 0);
liste_supprimer(&f->liste, 0);
return
etu
resultat;
esu tat;
}
Analyse et programmation 2 - Listes, files et piles
44
Variantes des listes : les files
Implémentation basée sur la liste tableau - Analyse
• Difficulté de programmation ?
• Efficacité d’exécution ?
– Opération défiler :
• Décalage des éléments de la liste.
• Opé
Opération
at o ttrès
ès coûteuse lo
lorsque
sque la file
le dev
devient
e t ggrande.
a de.
– Avec des tableaux dynamiques :
• Lenteur lors du redimensionnement, surtout avec les grands tableaux.
– Avec des tableaux fixes
• Capacité limitée de la pile
• Sur-occupation de mémoire.
Analyse et programmation 2 - Listes, files et piles
45
23
Les listes chaînées
Introduction
• Limitations des listes tableaux
– Taille fixe
fi e
– Coût élevé des opérations entrainant un déplacement des
éléments.
– Coût proportionnel à la taille de la liste.
– Inapproprié pour de très grandes listes.
• Alternative
– Les listes chaînées.
chaînées
– Autre façon de représenter les listes en mémoire.
Analyse et programmation 2 - Listes, files et piles
46
Structures de donnée récursives
Introduction – Rappel sur la récursivité
• Formulation récursive d’une fonction
– Une fonction récursive est une fonction qui ss’appelle
appelle elle-même.
elle-même
• Exemple : définition récursive de la factorielle
U0 = 1
Un = n * Un-1
• Mise en œuvre
long factorielle(long n)
{
if (n == 0)
return 1;
else
return n * factorielle(n - 1);
}
Analyse et programmation 2 - Listes, files et piles
47
24
Structures de donnée récursives
Introduction
• Structure de données récursive
– Une structure
str ct re de données q
quii se référence elle
elle-même.
même
• Exemple : définition récursive d’une liste
– Une liste c’est
• Soit vide.
• Soit une valeur, suivie d’une autre liste.
– Ce qui peut s’écrire
Liste ::= {} | { Valeur,
, Liste }
– Cette définition s’appuie donc récursivement sur elle-même.
• Illustration
{}
{ 0, { 1, { 2, { 3, { 4, {} } } } } }
Analyse et programmation 2 - Listes, files et piles
48
TDA Pile chaînée
Déclaration du type de données en langage C
typedef double ELEMENT;
struct CELLULE_PILE_CHAINEE
{
ELEMENT element;
struct CELLULE_PILE_CHAINEE * suivant;
};
typedef struct
{
struct CELLULE_PILE_CHAINEE * sommet;
} PILE_CHAINEE;
Analyse et programmation 2 - Listes, files et piles
49
25
TDA Pile chaînée
Représentation en mémoire - fonctionnement
• Empilage de 10, 20, 30
CELLULE
CELLULE
CELLULE
element: 30
suivant
element: 20
suivant
element: 10
suivant: NULL
PILE_CHAINEE
sommet: NULL
sommet
Analyse et programmation 2 - Listes, files et piles
50
TDA Pile chaînée
Représentation en mémoire – fonctionnement par étape - empilage
• Empilage de 10, 20, 30
CELLULE
element: 10
suivant: NULL
PILE_CHAINEE
PILE_CHAINEE
sommet
sommet: NULL
PILE_CHAINEE
Sommet: NULL
CELLULE
element: 20
suivant
PILE_CHAINEE
PILE_CHAINEE
sommet
sommet: NULL
Analyse et programmation 2 - Listes, files et piles
CELLULE
element: 10
suivant: NULL
CELLULE
element: 30
suivant
CELLULE
element: 20
suivant
CELLULE
element: 10
suivant: NULL
PILE_CHAINEE
PILE_CHAINEE
sommet
sommet: NULL
51
26
TDA Pile chaînée
Représentation en mémoire – fonctionnement par étape - dépilage
• Dépilage de 30, 20, 10
CELLULE
element: 30
suivant
CELLULE
element: 20
suivant
CELLULE
element: 10
suivant: NULL
PILE_CHAINEE
sommet
CELLULE
element: 30
suivant
CELLULE
element: 20
suivant
CELLULE
element: 10
suivant: NULL
PILE_CHAINEE
sommet
CELLULE
element: 20
suivant
PILE_CHAINEE
sommet
CELLULE
element: 10
suivant: NULL
CELLULE
element: 10
suivant: NULL
PILE_CHAINEE
sommet: NULL
Analyse et programmation 2 - Listes, files et piles
52
TDA Pile chaînée
Opérations
void pile_initialiser(PILE_CHAINEE * pile);
int pile_vide(PILE_CHAINEE * pile);
int pile_nombre_element(PILE_CHAINEE
pile nombre element(PILE CHAINEE * pile)
pile);
void pile_empiler(PILE_CHAINEE * pile, ELEMENT e);
ELEMENT pile_depiler(PILE_CHAINEE * pile);
Analyse et programmation 2 - Listes, files et piles
53
27
TDA Pile chaînée
Opérations
void pile_initialiser(PILE_CHAINEE * pile)
{
pile->sommet = NULL;
}
int pile_vide(PILE_CHAINEE * pile)
{
return pile->sommet == NULL;
}
Analyse et programmation 2 - Listes, files et piles
54
TDA Pile chaînée
Opérations
void pile_empiler(PILE_CHAINEE * pile, ELEMENT e)
{
struct
t
t CELLULE_PILE_CHAINEE
CELLULE PILE CHAINEE * nouvelle_cellule;
ll
ll l
// Allocation d'une nouvelle cellule
nouvelle_cellule = (struct CELLULE_PILE_CHAINEE *)
malloc(sizeof(struct CELLULE_PILE_CHAINEE));
// mémoriser la valeur de l'élément empilé
nouvelle_cellule->element = e;
// Placer la pile actuelle après la nouvelle cellule
nouvelle_cellule->suivant = pile->sommet;
// Le nouvel élément est le nouveau sommet de la pile
pile->sommet = nouvelle_cellule;
}
Analyse et programmation 2 - Listes, files et piles
55
28
TDA Pile chaînée
Opérations
ELEMENT pile_depiler(PILE_CHAINEE * pile)
{
struct CELLULE_PILE_CHAINEE * cellule_depilee;
ELEMENT resultat;
if (!pile_vide(pile))
{
// Dépilage du sommet de la pile
cellule_depilee = pile->sommet;
// Le nouveau sommet est la suite de la cellule depilee
pile->sommet = pile->sommet->suivant;
// La valeur depilee est la valeur de la cellule depilee
resultat = cellule_depilee->element;
// Liberation de la memoire
free(cellule_depilee);
}
else
{
printf("Erreur\n");
resultat = 0;
}
return resultat;
}
Analyse et programmation 2 - Listes, files et piles
56
TDA Pile chaînée
Opérations
int pile_nombre_element(PILE_CHAINEE * pile)
{
struct CELLULE_PILE_CHAINEE * courant;
int nombre = 0;
courant = pile->sommet;
while (courant != NULL)
{
nombre++;
courant = courant->suivant;
}
return nombre;
}
Analyse et programmation 2 - Listes, files et piles
57
29
TDA Pile chaînée
Analyse
• Avantages
– Espace mémoire utilisé
tilisé en fonction du
d besoin
besoin.
– Implémentation efficace, même pour de très grandes piles.
• Inconvénients
– L’allocation et la libération de mémoire sont des opérations assez
coûteuses.
– Risque de fragmentation de la mémoire.
– Le temps nécessaire à une allocation est très variable.
variable
• Inapproprié pour des applications critiques en temps.
Analyse et programmation 2 - Listes, files et piles
58
TDA File chaînée
Principe
• On conserve un pointeur sur le début et sur la fin.
• Enfilage
E fil
à lla fi
fin.
• Défilage au début.
Analyse et programmation 2 - Listes, files et piles
59
30
TDA File chaînée
Déclaration du type de données en langage C
typedef double ELEMENT;
struct CELLULE_FILE_CHAINEE
{
ELEMENT element;
struct CELLULE_FILE_CHAINEE * suivant;
};
typedef struct
{
struct CELLULE_FILE_CHAINEE * debut;
struct CELLULE_FILE_CHAINEE * fin;
} FILE_CHAINEE;
Analyse et programmation 2 - Listes, files et piles
60
TDA File chaînée
Représentation en mémoire – fonctionnement de l’enfilage
• Enfilage 10, 20, 30
CELLULE
CELLULE
CELLULE
element: 10
suivant: NULL
suivant
element: 20
suivant: NULL
suivant
element: 30
suivant: NULL
PILE_CHAINEE
FILE_CHAINEE
debut: NULL
debut
fin: NULL
fin
Analyse et programmation 2 - Listes, files et piles
61
31
TDA File chaînée
Représentation en mémoire – fonctionnement de l’enfilage
• Enfilage de 10, 20, 30
CELLULE
element: 10
suivant: NULL
FILE_CHAINEE
debut: NULL
fin: NULL
FILE_CHAINEE
debut
fin
CELLULE
CELLULE
CELLULE
CELLULE
CELLULE
element: 10
suivant: NULL
suivant
element: 20
suivant: NULL
element: 10
suivant: NULL
suivant
element: 20
suivant: NULL
suivant
element: 30
suivant: NULL
FILE_CHAINEE
debut
fin
FILE_CHAINEE
debut
fin
Analyse et programmation 2 - Listes, files et piles
62
TDA File chaînée
Représentation en mémoire – fonctionnement du défilage
• Defilage de 10, 20, 30
CELLULE
element: 10
suivant: NULL
suivant
CELLULE
element: 20
suivant: NULL
suivant
CELLULE
element: 30
suivant: NULL
CELLULE
CELLULE
element: 20
suivant
element: 30
suivant: NULL
FILE_CHAINEE
debut
fin
FILE_CHAINEE
debut
fin
CELLULE
element: 30
suivant: NULL
FILE_CHAINEE
debut: NULL
fin: NULL
Analyse et programmation 2 - Listes, files et piles
63
32
TDA File chaînée
Opérations
void file_initialiser(FILE_CHAINEE * file);
int file_vide(FILE_CHAINEE * file);
int file_nombre_element(FILE_CHAINEE
file nombre element(FILE CHAINEE * file)
file);
void file_enfiler(FILE_CHAINEE * file, ELEMENT e);
ELEMENT file_defiler(FILE_CHAINEE * file);
Analyse et programmation 2 - Listes, files et piles
64
TDA File chaînée
Opérations
void file_initialiser(FILE_CHAINEE * file)
{
file->debut = NULL;
file->fin = NULL;
}
int file_vide(FILE_CHAINEE * file)
{
return file->debut == NULL;
}
Analyse et programmation 2 - Listes, files et piles
65
33
TDA File chaînée
Opérations
void file_enfiler(FILE_CHAINEE * file, ELEMENT e)
{
struct
t
t CELLULE_FILE_CHAINEE
CELLULE FILE CHAINEE * nouvelle_cellule;
ll
ll l
// Allocation d'une nouvelle cellule
nouvelle_cellule = (struct CELLULE_FILE_CHAINEE *)
malloc(sizeof(struct CELLULE_FILE_CHAINEE));
// mémoriser la valeur de l'élément empilé
nouvelle_cellule->element = e;
nouvelle_cellule->suivant = NULL;
if (file->fin != NULL)
// Placer le nouvel élément à la fin
file->fin->suivant = nouvelle_cellule;
else
// Premier element, c'est aussi le debut
file->debut = nouvelle_cellule;
// La nouvelle cellule est à la fin
file->fin = nouvelle_cellule;
}
Analyse et programmation 2 - Listes, files et piles
66
TDA File chaînée
Opérations
ELEMENT file_defiler(FILE_CHAINEE * file)
{
struct CELLULE_FILE_CHAINEE * cellule_defilee;
ELEMENT resultat;
if (!file_vide(file))
{
// Défilage du debut de la file
cellule_defilee = file->debut;
// Le nouveau debut est la suite de la cellule defilee
file->debut = file->debut->suivant;
// La valeur defilee est la valeur de la cellule defilee
resultat = cellule_defilee->element;
// Liberation de la memoire
free(cellule_defilee);
}
else
{
printf("Erreur\n");
resultat = 0;
}
return resultat;
}
Analyse et programmation 2 - Listes, files et piles
67
34
TDA File chaînée
Opérations
int file_nombre_element(FILE_CHAINEE * file)
{
struct CELLULE_FILE_CHAINEE * courant;
int nombre = 0;
courant = file->debut;
while (courant != NULL)
{
nombre++;
courant = courant->suivant;
}
return nombre;
}
Analyse et programmation 2 - Listes, files et piles
68
TDA Liste chaînée
Introduction
• La file ressemble fortement à une liste.
• Pour
P
obtenir
bt i lle TDA li
liste,
t il suffit
ffit d’
d’y ajouter
j t quelques
l
opérations :
ELEMENT liste_element(LISTE_CHAINEE * liste, int position);
void liste_inserer(LISTE_CHAINEE * liste, int position, ELEMENT e);
void liste_supprimer(LISTE_CHAINEE * liste, int position);
• L’implantation
p
de ces opérations
p
se fait de façon
ç similaire.
Analyse et programmation 2 - Listes, files et piles
69
35
Structures chaînées
Optimisations
• Compteur d’élément
– Il est possible d’intégrer un
n compte
compteurr d’éléments dans la
structure.
– Améliore les performances des opérations nécessitant le nombre
d’éléments.
• Recyclage des blocs alloués
– L’allocation et la libération des blocs est coûteuse en temps.
– Il est p
possible de construire une liste g
globale des blocs libérés.
– Utilisation prioritaire de ces blocs en réserve avant toute nouvelle
allocation.
Analyse et programmation 2 - Listes, files et piles
70
Structures dynamiques et systèmes critiques
Recommandations
• En raison de la fragmentation de la mémoire
– L’allocation d
dynamique
namiq e pe
peutt écho
échouer
er après des millions de ssuccès.
ccès
– Les temps d’allocation sont en général peu prévisibles.
• Utilisation des structures dynamiques
– Déconseillée, voire même interdite, pour les systèmes critiques.
– Exemples
• Systèmes vitaux dans le domaine médical
• Automobile
• Spatial
– Dans ces domaines, l’allocation dynamique peut être utilisée
seulement pendant les phases d’initialisation du logiciel.
Analyse et programmation 2 - Listes, files et piles
71
36
Autres structures couramment utilisées
Listes doublement chaînées
• Intérêt
– Simplification des algorithmes nécessitant l’élément précédent
• Ex: suppression.
– Parcours efficace dans les deux sens.
CELLULE
CELLULE
CELLULE
element: 10
suivant: NULL
suivant
precedent:NULL
element: 20
suivant: NULL
suivant
precedent
element: 30
suivant: NULL
precedent
LISTE_DOUBLE_CHAINEE
debut
fin
Analyse et programmation 2 - Listes, files et piles
72
Autres structures couramment utilisées
Arbres
• Représentation de hiérarchies.
– Une cellule
cell le pointe vers
ers 2 o
ou plusieurs
pl sie rs cell
cellules
les filles
filles.
– Une cellule n’est pointée qu’une seule fois.
Analyse et programmation 2 - Listes, files et piles
73
37
Autres structures couramment utilisées
Graphes
• Représentation de structures complexes.
– Une cellule
cell le pointe vers
ers une
ne ou
o plusieurs
pl sie rs cell
cellules.
les
– Une cellule est pointée par une ou plusieurs cellules.
Analyse et programmation 2 - Listes, files et piles
74
Qu’avons-nous appris ?
• Les TDA Liste, File et Pile.
• L’implémentation
L’i lé
t ti par ttableau.
bl
• L’implémentation avec les structures de données
récursives.
Analyse et programmation 2 - Listes, files et piles
75
38
Vos questions
Analyse et programmation 2 - Listes, files et piles
76
Analyse et programmation 2 - Listes, files et piles
77
39
Téléchargement
Random flashcards
amour

4 Cartes mariam kasouh

Ce que beaucoup devaient savoir

0 Cartes Jule EDOH

découpe grammaticale

0 Cartes Beniani Ilyes

TEST

2 Cartes Enrico Valle

Créer des cartes mémoire