0% ont trouvé ce document utile (0 vote)
148 vues61 pages

Structures de Données : Files et Listes

Le document décrit les structures de données files et listes. Il présente leur fonctionnement, leur représentation et les opérations associées comme l'insertion, la suppression et l'accès aux éléments. Différentes implémentations sont également abordées.

Transféré par

Aalae Goudal
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
148 vues61 pages

Structures de Données : Files et Listes

Le document décrit les structures de données files et listes. Il présente leur fonctionnement, leur représentation et les opérations associées comme l'insertion, la suppression et l'accès aux éléments. Différentes implémentations sont également abordées.

Transféré par

Aalae Goudal
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Cours Complexité des Algorithmes

Structure d données : files,listes

Prof. A. BOUZIDI
File d’attente / patients Files d’attente / pages

• Une file est une structure linéaire permettant de stocker et de restaurer


des données selon un ordre FIFO (First In First Out "Premier Entré
Premier Sorti" ).
• Dans une file:
• Les insertions (enfilement) se font à une extrémité appelé queue de la file.
• Les suppressions (défilement) se font à l’autre extrémité appelé tête de la file.
File F

1 12 37 53 9

Queue Tête

Défiler F 1 12 37 53 9

Enfiler Elem de val 8 F 8


• Type File
• Utilise Elément, Booléen
• Opérations
✓ file_vide : → File
✓ est_vide : File → Booléen
✓ enfiler : File x Elément → File
✓ défiler : File → File
✓ tête : File → Elément
• Pré conditions
• défiler(f) est_défini_ssi est_vide(f) = faux
• tête(p) est_défini_ssi est_vide(f) = faux
• Axiomes
• Soit E : Elément , F: File
• est_vide(file_vide) = Vrai
• est_vide(enfiler(F, E)) = Faux
• Si (est_vide(F) = vrai) alors tête(enfiler(F, E)) = e
• Si (est_vide(F) = faux) alors tête(enfiler(F, E)) = tête(f)
• Si (est_vide(F) = vrai) alors défiler(enfiler(f F, E)) = file_vide
• Si (est_vide(F) = faux) alors défiler(enfiler(F, E)) = enfiler(défiler(F), E))
• File_vide: → File
• Initialisation de la file : création d’une file vide
• Est_vide: File → Booléen
• Tester si la file est vide
• Enfiler : File X Elément → File
• Ajouter un élément à la file
• Défiler : File → File
• Supprimer l’élément entête de la file
• Tête : File → Elément
• Consulter l’élément en tête de la file.
• Représentation contigüe (par tableau)
• Les éléments de la file sont rangés dans un tableau
• Deux entiers représentent respectivement les indices des positions de la tête et
de la queue de la file.

• Représentation chaînée (par pointeurs)


• Les éléments de la file sont chaînées entre eux
• Un pointeur sur le premier élément de la file représente la file et désigne la
tête de la file
• Un pointeur sur le dernier élément désigne la queue de la file
• Une file vide est représentée par le pointeur NULL (en C)
• tête de file : position précédant le premier élément
• queue de file :position du dernier élément

• Initialisation:
• tête ← -1
• queue ← -1

• Inconvénient :
• on ne peut plus ajouter un élément dans la file alors qu’elle n’est pas pleine
typedef int Element ;

typedef struct Cellule{ ?


Element valeur;
struct Cellule * suivant;
} Cellule;

typedef struct File{


struct Cellule * tete; tête queu
struct Cellule * queu;
}File;

File file_vide();
File file_enfiler(File f,Element e);
File file_defiler(File f);
Element file_tete(File f);
Booleen est_videF(File f);
File file_vide(){
[Link]=[Link]=NULL;
return f;
}

Booleen est_videF(File f){


if (([Link]==NULL) || ([Link] ==NULL))
return true;
else
return false;
}
File file_enfiler(File f,Element e){

Cellule * Ctemp =(Cellule *)malloc(sizeof(Cellule));


Ctemp->valeur=e;
Ctemp->suivant=NULL;
if (est_videF(f)==true)
[Link]= Ctemp;
[Link]=Ctemp;
else{
[Link]=Ctemp;
[Link]=Ctemp;
}
return f;
}
File file_defiler(File f){
if (est_videF(f)==true)
printf("Erreur :file vide !");
else{
[Link]=[Link]->suivant;
if([Link] == null)
[Link] = null;
}
return f;
}
Soit une file F d’éléments entiers,

• Implémenter les fonctions/opérations de base de votre file.


• Écrire une procédure qui permet de remplir la file par l’utilisateur.
• Écrire une procédure qui affiche tous les éléments de la file.
• Écrire le programme principale qui demande à l’utilisateur de remplir la
file, et à la fin, il affiche les éléments enregistrés.
Soit une file F d’éléments entier,

• Implémenter les fonctions/opérations de base de votre file.


• Ecrire une fonction qui affiche les nombres des éléments de la file.
• Ecrire une procédure qui affiche tous les éléments de la file.
• Ecrire la fonction max qui affiche la valeur maximal, ainsi que son ordre.
• Ecrire la fonction min qui affiche la valeur minimale, ainsi que son ordre.
• Ecrire la fonction moy qui affiche la valeur moyenne.
Soit une file F et une pile P d’éléments entier,

• Peut on inverser une file par l’utilisation d’une pile?

• Si oui, écrire une procédure permettant d’inverser une file.


Cours Complexité des Algorithmes
Structure d données : file

Prof. A. BOUZIDI
• Généralisation des piles et des files :
• Structure linéaire dans laquelle les éléments peuvent être traités les uns à la suite
des autres
• Ajout ou retrait d’élément n’importe ou dans la liste
• Accès à n’importe quel élément
• Une liste est une suite finie, d’éléments de même type repérés par leur
rang dans la liste.
• Chaque élément de la liste est rangé à une certaine place
• Les éléments de la liste sont ordonnés en fonction de leur place
• La longueur d’une liste est le nombre totale de ses éléments
Type Liste
▪ Utilise Elément, Booléen, Place
Opérations
▪ liste_vide : → Liste
▪ longueur : Liste → Entier
▪ inserer : Liste x Elément → Liste
▪ supprimer : Liste → Liste
▪ kème : Liste x Entier → Elément
▪ accès : Liste x Entier → Place
▪ contenu : Liste x Place → Elément – contenu : Liste x Place → Elément
▪ succ : Liste x Place → Place
Pré conditions
▪ inserer(l,k,e) est_défini_ssi 1 ≤k ≤ longueur(l)+1
▪ supprimer(l,k) est_défini_ssi 1 ≤k ≤ longueur(l)
▪ kème(l,k) est_défini_ssi 1 ≤k ≤ longueur(l)
▪ accès(l,k) est_défini_ssi 1 ≤k ≤ longueur(l)
▪ succ(l,p) est_défini_ssi p≠ accès(l,longueur(l))
• liste_vide : → Liste
• Opération d’initialisation : la liste créée est vide,
• longueur : Liste →Entier
• Retourne le nombre d’éléments dans une liste,
• inserer : Liste x Elément → Liste
• Ajoute un élément à la liste dans une position donnée,
• supprimer : Liste → Liste
• Supprimer un élément dans la liste,
• kème : Liste x Entier → Elément
• Fournit l’élément de rang donné dans une liste, Fournit l’élément de rang donné dans une liste,
• accès : Liste x Entier → Place
• Connaître la place de rang donné,
• contenu : Liste x Place → Elément
• Connaitre l’élément d’une place donnée,
• succ : Liste x Place → Place
• Passer d’une place à la place suivante.
• Concatener: Liste × Liste → Liste
• Accroce une deuxième liste en entré à la fin de la première.

• est_exist : Liste × Element → Booléen


• Tester si un élément exist dans la liste
• Représentation contigüe (par tableau)
• Les éléments sont rangés les uns côté des autres dans un tableau
• La kème case du tableau contient le kème élément de la liste.
• Le rang est égale à la place : ce sont des entiers
// taille maximale Liste
#define MAX_LISTE 10

//type des éléments


typedef int Element;
//type place
typedef int Place;

typedef struct {
Element tab[MAX_FILE];
int taille;
} Liste ;
/* fichier "Tliste.h " */
// définition du type liste complémentaire par tableau
#define MAX_LISTE 100 /* taille maximale de la liste */
typedef int Element /* les éléments sont des entiers */
typedef int Place /* place = rang (est un entier) */
typedef struct {
Element tab[MAX_LISTE] ;/*éléments de la liste */
int taille ;
} Liste;
// Déclaration des fonctions gérant la liste
Liste liste_vide()
int longueur(Liste l);
Liste inserer(Liste l,int i, Element e);
Liste supprimer(Liste l, int i);
Element keme (Liste l, int k);
Place acces(Liste l, int i);
Element contenu(Liste l, Place i);
Place succ (Liste l, Place i);
• Représentation contigüe (par tableau)
• Les éléments sont rangés les uns côté des autres dans un tableau
• La kème case du tableau contient le kème élément de la liste.
• Le rang est égale à la place : ce sont des entiers
• Représentation chaînée (par pointeurs)
• Les éléments ne sont pas rangés les uns à côté des autres.
• La place d’un élément est l’adresse d’une structure qui contient l’élément, ainsi que la place de
l’élément suivant.
• Utilisation de pointeurs pour chaîner entre eux les éléments successifs
• En langage C la liste est représentée par un pointeur sur une structure
• La structure contient une élément de la liste et un pointeur sur l’élément suivant.
• La liste vide est représentée par une constante prédéfinie vide (NULL en C/C++)
//type des éléments
typedef int Element;
//type place
typedef struct cellule* Place;
//type cellule
typedef struct {
Element valeur;
Struct cellule *suivant;
} Cellule ;
//type Liste
typedef struct Liste{
Cellule *premier;
};
typedef int Element;
typedef struct Cellule{
Element valeur;
Struct cellule *suivant;
} Cellule ;
typedef struct cellule* Place;
//type Liste
typedef Cellule* Liste;

Liste liste_vide()
int longueur(Liste l);
Liste inserer(Liste l, Element e);
Liste inserer(Liste l,int i, Element e);
Liste supprimer(Liste l, int i);
Element keme (Liste l, int k);
Place acces(Liste l, int i);
Element contenu(Liste l, Place i);
Place succ (Liste l, Place i);
Liste liste_vide() {
return NULL;
}
int longueur(Liste l) {
int taille=0; Liste p=l;
while(p) {
taille++; p = p->suivant;}
return taille;
}

Liste inserer(Liste L, Element e) {


Liste nvelem =(Liste)malloc(sizeof(Cellule));
nvelem ->valeur=e;
nvelem ->suivant = L;
L = nvelem ;
return L;
}
//inserer une element e dans la position i
Liste inserer(Liste L, int i, Element e) {
if (i<0 || i>longueur(L)){
printf(" Erreur : rang non valide !\n");
exit(-1); }
Cellule* nv =(Cellule*)malloc(sizeof(cellule));
nv ->valeur=e;
nv ->suivant =NULL;
if (i==0){
nv->suivant =L;
L=nv; }
else {
List temp = L;
for (int j=0; j<i-1; j++)
temp = temp ->suivant;
nv->suivant = temp ->suivant;
temp -> suivant =nv;
}
return L;
}
Place acces(Liste L, int k){
int i;
Cellule* p;
If (k<0 || k>=longueur(l) { printf("Erreur : rang invalide !\n"); exit(-1); }
If (k==0) return L;
else {
p=L;
for (i=0; i<k; i++)
p= p->suivant;
return p;
}
}
Element contenu(Liste l, Place i){Element contenu(Liste l, Place i){
If (longueur(l) ==0) { printf(" Erreur : liste vide !\n ");
exit(-1); }
Return p->valeur; }

Place succ (Liste l, Place p){


if (p->suivant == NULL) {
printf("Erreur : suivant dernière place !\n");
exit(-1); }
return p->suivant; }
Liste inserer(Liste L,int i, Element e){
if (i<0 || i>longueur(L))
{ printf("Erreur : rang non valide !\n"); exit(-1); }
Liste cl =(Liste)malloc(sizeof(Cellule));
cl->valeur=e; cl>suivant=NULL;
if (i==0) { cl->suivant =L; L=cl; }
else {
int j; Liste p=L;
for (j=0; j<i-1;j++) p=p->suivant;
cl->suivant = p->suivant;
p->suivant = cl;
return L;
}
Liste supprimer(Liste L, int i){
int j;
Liste p;
if (i<0 || i>= longueur(L)) {
printf("Erreur : rang non valide !\n"); exit(-1); }
if (i == 0) {
p=L; L=L->suivant; }
else {
place q;
q=acces(l, i-1); p= succ(l,q);
q->suivant = p->suivant; }
free(p);
return L; }
• Liste avec tête fictive
• Mettre en tête de liste une zone qui ne contient pas de valeur et reste toujours en tête
• Liste chaînée circulaire
• Le suivant du dernier élément de la liste est le premier élément
• Liste doublement chaînée
• Utiliser un double chaînage; chaque place repérant à la fois la place qui la précède et
celle qui la suit
• Liste doublement chaînée circulaire
• Comme liste doublement chaînée et en plus le suivant du dernier élément de la liste
est le premier élément
• Liste triée
• L’ordre des enregistrements dans la liste respecte l’ordre sur les clés
• Soit n le nombre d’éléments d’une liste
Ecrire un programme en langage C qui contient les fonctions suivantes :
• Crée une liste simplement chainée d’employés caractérisés par leur
code, nom, prénom et salaire (la fin de saisie nom égale à FIN).
• Recherche un employé donné selon son code.
• Supprime un employé donné (s’il existe), sachant son code.
• Affiche le nom des employés qui ont un salaire supérieur à la
moyenne.
• Vérifie si la liste est triée (salaire).
• Trie la liste selon l’ordre croissant des salaires.
typedef struct empElement {
int code;
char *nom;
char *prenom;
float sal;
struct empElement *suivant;
}emp ;
typedef struct empElement *liste;
liste ajouter(liste l);
liste rechercher(liste l,int code);
liste supprimer(liste l, int code);
void afficher(liste l);
void afficheliste(liste l);
int verifier(liste l);
liste tri(liste l);
liste inserer (liste l,emp e)
{
liste p = (liste)malloc(sizeof(emp));
p->code = [Link];
p->nom=(char*)malloc(25*sizeof(char));
p->prenom=(char*)malloc(25*sizeof(char));
strcpy(p->nom,[Link]);
strcpy(p->prenom,[Link]);
p->sal = [Link];
p->suivant = NULL;
if( l == NULL)
l = p;
else
{
p->suivant = l;
l=p;
}
return l;
}
liste ajouter(liste l)
{
emp e;
do
{
printf("entrer le code de l'employee \n");
scanf("%d",&[Link]);
[Link]=(char*)malloc(25*sizeof(char));
printf("entrer le nom de l'employee \n");
scanf("%s",[Link]);
if(strcmp([Link],"FIN")!=0)
{
[Link]=(char*)malloc(25*sizeof(char));
printf("entrer le prenom de l'employee \n ");
scanf("%s",[Link]);
printf("entrer le salaire de l'employee \n");
scanf("%f",&[Link]);
l=inserer(l,e);
}
}while(strcmp([Link],"FIN")!=0);
return l;
}
liste rechercher(liste l,int code)
{
liste p;
p=l;
while((p!=NULL) && (p->code!=code )){
p=p->suivant;
}
return p;
}
liste supprimer(liste l, int code){
liste q, p;
if(l==NULL){
printf("erreur: liste est vide");
exit(-1);}
p=l;
if(p->code==code){
l=l->suivant;
free(p);
return l;}
q=p->suivant;
while (q!=NULL&& q->code!=code){
q=q->suivant;
p=p->suivant;
}
if(q!=NULL){
p->suivant=q->suivant;
free(q);}
return l;}
float moyenne(liste l)
{
liste p;
p=l;
float s=0;
int n=0;
while(p!=NULL){
s+=p->sal;
n++;
p=p->suivant;
}
if(n!=0)
return s/(float)n;
}
void afficher(liste l)
{
float m=moyenne(l);
liste p=l;
while(p)
{
if(p->sal>=m)
{
printf("code=%d\n",p->code);
printf("nom = %s\n",p->nom);
printf("prenom = %s\n",p->prenom);
printf("salaire=%f\n",p->sal);
}
p=p->suivant;
}
}
void afficheliste(liste l)
{
liste p=l;
while(p)
{
printf("code=%d\n",p->code);
printf("nom = %s\n",p->nom);
printf("prenom = %s\n",p->prenom);
printf("salaire=%f\n",p->sal);
p=p->suivant;
}
}
int verifier(liste l){
liste p = l;
if(p==NULL) return 1;
if(p->suivant == NULL) return 1;
while(p->suivant != NULL){
if(p->sal>p->suivant->sal)
return 0;
p = p->suivant;
}
return 1;
}
liste tri(liste l)
{liste p;
int ech;
do{
ech=0; printf("%d ",ech);
for(p=l;p->suivant;p=p->suivant)
{
if(p->sal >p->suivant->sal)
{ech=1;
liste q=(emp*)malloc(sizeof(emp));
q->code=p->code;
q->nom=(char*)malloc(20*sizeof(char));
strcpy(q->nom,p->nom);
q->prenom=(char*)malloc(30*sizeof(char));
strcpy(q->prenom,p->prenom);
q->sal=p->sal;
p->code=p->suivant->code;
strcpy(p->nom,p->suivant->nom);
strcpy(p->prenom,p->suivant->prenom);
p->sal=p->suivant->sal;
p->suivant->code=q->code;
strcpy(p->suivant->nom,q->nom);
strcpy(p->suivant->prenom,q->prenom);
p->suivant->sal=q->sal;
}
}
}while(ech!=0);
return l;
}
void menu(liste l){
int choix;
int code;
emp e;
do{
printf("*************MENU*****************\n");
printf("1:saisir une liste d'employer\n");
printf("2: rechercher un employer selon son code\n");
printf("3: supprimer un employer \n");
printf("4: afficher les employes dont le salaire est superieur a la

moyenne \n");

printf("5: afficher la liste des employes \n");


printf("6: verifie si la liste est trier \n");
printf("7:trier la liste\n");
printf("8: quitter \n" );
printf(" saisir votre choix \n");
scanf("%d",&choix);
switch(choix){
case 1 : l=ajouter(l); break;
case 2 : printf("donner le code de l'employé à rechercher:");
scanf ("%d", &code);
liste p;
p=rechercher(l,code);
if(p==NULL){printf("employé inexistant \n");
}
else {
printf("nom=%s", p->nom);
printf("prenom=%s", p->prenom);
printf("salaire=%f", p->sal);
}break;
case 3: printf("donner le code de l'employé à supprimer:");
scanf ("%d", &code);
l=supprimer(l,code);
break;
case 4:if(l==NULL)
printf("liste vide \n");
else
afficher(l); break;
case 5:if(l==NULL) printf("liste vide \n");
else
afficheliste(l);
break;
case 6: if(verifier(l))
printf("liste triee\n");
else
printf("liste non triee\n");
break;
case 7: if (l) { l=tri(l);
printf("tri effectu\202\n");}
break;
}
}while(choix!=8); }
int main(int argc, char *argv[]) {
liste l=malloc(sizeof(emp));
l=NULL;
menu(l);
system("pause");
return 0;
}
la différence entre les liste simplement chaînée et liste doublement chaînée est que
les maillons d'une liste doublement chaînée possèdent un pointeur sur l'élément qui les
précèdent :

Pointeur sur l’élément précédant Pointeur sur le maillon suivant


Données
• Pour obtenir la structure de base d'une liste doublement chaînée, il suffit
d'ajouter un pointeur sur l'élément précédent dans la structure simple

typedef struct cellule


{
int donnees;
struct noeud *precedent;
struct noeud *suivant;
} cellule;
typedef cellule *liste;
liste

10 15,5 8,75

14,5
Null

Les listes chaînées bidirectionnelles sont utilisées dans le cas où on


a besoin d’établir des retour en arrière.
Créer les types nécessaires pour la mise en œuvre d'une liste
chaînée bidirectionnelle d’entiers. On prévoit trois fonctions : la
première pour ajouter une valeur en tête de liste, la deuxième pour
afficher la liste à l'écran, et la troisième pour vider la liste et libérer
l'espace mémoire.
typedef int Element;
typedef struct cellule2c {
Element valeur;
struct cellule2c *suivant;
struct cellule2c *precedant;
}cellule2c;

typedef cellule2c *liste2c;

liste2c liste2c_vide();
int liste2c_est_vide(liste2c l);
liste2c ajouter(liste2c l,Element e);
liste2c vider (liste2c l);
liste2c liste2c_vide() {
return NULL;
}
int liste2c_est_vide(liste2c l) {
if(l==NULL)
return 1;
return 0;
}
liste2c ajouter(liste2c l,Element e) {
liste2c p=(liste2c)malloc(sizeof(cellule2c));
p->valeur=e; p->suivant=NULL;
p->precedant=NULL;
if(l==NULL){
p->precedant=l;
l=p; return l;
}
l->precedant=p;
p->suivant=l;
l=p;
p->precedant=l;
return l;
}
liste2c vider(liste2c l) {
if(l==NULL)
printf("erreur liste vide \n");
liste2c p;
while(l!=NULL) {
p=l;
l=l->suivant;
free(p);
}
return l; }
void afficher(liste2c l) {
if(l==NULL){
printf("erreur liste vide \n");
}
else {
liste2c p=l;
while(p!= NULL) {
printf("%d \n",p->valeur);
p=p->suivant;
}
}
}
void menu(liste2c l) {
int choix, e;
l=NULL;
do{
printf("Choisissez....\n");
printf("[Link] un élément en tête de liste\n");
printf("[Link] la liste\n");
printf("[Link] les éléments de la liste\n");
printf("[Link] \n");
printf("Votre choix: ");
scanf("%d", &choix);
switch(choix) {
case 1: printf("Donnez un entier\n");
scanf("%d", &e);
l=ajouter(l,e);
break;
case 2: l=vider(l); break;
case 3: afficher(l); break;
}
}while(choix!=4); };

Vous aimerez peut-être aussi