Skip to content
Snippets Groups Projects
Commit c3f942b8 authored by paul.albuquer's avatar paul.albuquer
Browse files

added source codes and handout for queues

parent 0d66be99
No related branches found
No related tags found
No related merge requests found
# Algorithmes et structures de données # Algorithmes et structures de données
# Structure de piles # Structure de pile
***** *****
......
# Algorithmes et structures de données
# Structure de file d'attente
*****
## 1. Définition
Une file d'attente ou queue est une structure de données dans laquelle la première information entrée est la première à ressortir (en anglais : FIFO, First In First Out)
On considère ici une implémentation de queue dynamique et donc à capacité « infinie » (dépend en réalité de la mémoire disponible).
## 2. Spécification de la structure
Si le type des éléments qu'on insère, n'est pas précisé, on parle de spécification générique.
Les opérations possibles sur une file d'attente (ou queue) en définissent l'interface :
* Opérations de manipulation
* Créer une liste vide
* Détruire une liste
* Insérer un nouvel élément en queue de la file d'attente
* Extraire un élément en tête de la file d'attente (i.e. le premier élément introduit)
*
* Fonctions de consultation
* Lire l'élément en tête de la file d'attente
* Lire l'élément en queue de la file d'attente
* Tester si la file d'attente est vide
L'interface de la file d'attente est l'ensemble des fonctionnalités offertes à l'utilisateur pour interagir
avec celle-ci.
## 3. Structure de file d'attente
On considère une liste chaînée d'articles avec deux pointeurs de tête et de queue. Chaque article comportera un champ pour stocker les valeurs dans cette liste et un champ contenant une variable de type accès pour assurer le chaînage. On considère à titre d'exemple le cas de valeurs entières.
Schématiquement:
![Illustration d'une file d'attente](./figures/fig_queue_representation.png)
L'accès à la file d'attente se fera par les pointeurs de tête et de queue.
Une telle file d'attente basée sur une liste chaînée sera déclarée par exemple sous la forme suivante:
```C
struct _element { // Elément de liste
int data;
struct _element* next;
} element;
struct _queue { // File d'attente:
element* tete; // tête de file d'attente
element* debut; // queue de file d'attente
}
```
## 4. Implémentation des fonctionnalité d'une file d'attente
### a) Consultations
On considère la fonction queue_est_vide qui teste si la file d'attente est vide et les fonctions `queue_tete` et `queue_debut` qui retournent l'élément en tête, respectivement en queue, de la file d'attente.
```C
bool queue_est_vide(queue fa) {
return (NULL == fa.tete && NULL == fa.debut);
}
int queue_tete(queue fa) {
assert(!queue_est_vide(fa));
return fa.tete­>data;
}
int queue_debut(queue fa) {
assert(!queue_est_vide(fa));
return fa.debut­>data;
}
```
### b) Manipulations
#### Insertion en queue de file d'attente
Voici l'entête de la fonction: `void queue_inserer(queue* fa,int val);`
Il faut considérer plusieurs cas:
* La file d'attente est vide
![Insertion dans une file d'attente vide](./figures/fig_empty_queue_insert.png)
* L'insertion se fait en queue d'une file d'attente non vide
![Insertion dans une file d'attente non-vide](./figures/fig_non_empty_queue_insert.png)
#### Extraction en tête de file d'attente
Voici l'entête de la procédure:
`int queue_extraire(queue* fa);`
On commence par récupérer, la valeur en tête de file d'attente via l'appel `queue_tete(*fa);`
Puis on met un pointeur temporaire sur l'élément en tête, avant de déplacer le pointeur de tête sur l'élément suivant.
Finalement, on désalloue la mémoire
![Extraction d'une file d'attente](./figures/fig_queue_extract.png)
Si la file d'attente n'avait qu'un seul élément, alors il faudrait mettre le pointeur `fa-­>debut` à `NULL`.
Dans ce cas, à la suite du point (3), le pointeur `fa-­>tete` se retrouve à `NULL`. On doit donc ajouter l'instruction :
```C
if (NULL == fa­>tete) {
fa­>debut = NULL;
}
```
lessons/figures/fig_empty_queue_insert.png

19.8 KiB

lessons/figures/fig_non_empty_queue_insert.png

29.3 KiB

lessons/figures/fig_queue_extract.png

23.7 KiB

lessons/figures/fig_queue_representation.png

7.08 KiB

#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <limits.h>
#include"queue_array_int.h"
bool queue_est_valide(queue fa) {
return (fa.capacite > 0 && fa.debut >= -1);
}
bool queue_est_vide(queue fa) {
assert(queue_est_valide(fa));
return (-1 == fa.debut);
}
bool queue_est_pleine(queue fa) {
assert(queue_est_valide(fa));
return (fa.capacite-1 == fa.debut);
}
int queue_count(queue fa) {
assert(queue_est_valide(fa));
return fa.debut+1;
}
int queue_tete(queue fa) {
assert(!queue_est_vide(fa));
return fa.data[0];
}
int queue_debut(queue fa) {
assert(!queue_est_vide(fa));
return fa.data[fa.debut];
}
queue queue_creer() {
queue fa;
fa.capacite = INCR;
fa.debut = -1;
fa.data = malloc(INCR*sizeof(int));
return fa;
}
void queue_resize(queue* fa,int max) {
assert(queue_est_valide(*fa));
if (max > fa->capacite) {
fa->capacite = max;
fa->data = realloc(fa->data,max*sizeof(int));
}
}
void queue_detruire(queue* fa) {
fa->capacite = -1;
fa->debut = INT_MIN;
free(fa->data);
}
void queue_inserer(queue* fa,int val) {
if (queue_est_pleine(*fa)) {
queue_resize(fa,fa->capacite+INCR);
}
fa->debut++;
fa->data[fa->debut] = val;
}
int queue_extraire(queue* fa) {
int val = queue_tete(*fa);
fa->debut--;
fa->data = memmove(fa->data,fa->data+1,queue_count(*fa)*sizeof(int));
return val;
}
#ifndef QUEUE_ARRAY_INT_H
#define QUEUE_ARRAY_INT_H
#include <stdbool.h>
const int INCR = 100;
typedef struct _queue {
int* data;
int debut; //tete à l'index 0
int capacite;
} queue;
//Créer une nouvelle queue vide
queue queue_creer();
//Libérer le tableau, mettre la capacité à < -1
void queue_detruire(queue* fa);
//Inserer un élement en début de queue
void queue_inserer(queue* fa,int val);
//Extraire un élément en tête de queue
int queue_extraire(queue* fa);
//Consulter l'élément en tête de queue
int queue_tete(queue fa);
//Consulter l'élément au début de queue
int queue_debut(queue fa);
//Tester si la queue est vide
bool queue_est_vide(queue fa);
//Compter du nombre d'éléments de la queue:
int queue_count(queue fa);
#endif
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include"queue_array_int.h"
bool queue_est_valide(queue fa) {
return (fa.capacite > 0 && fa.debut >= -1);
}
bool queue_est_vide(queue fa) {
assert(queue_est_valide(fa));
return (-1 == fa.debut);
}
bool queue_est_pleine(queue fa) {
// à compléter
}
int queue_count(queue fa) {
// à compléter
}
int queue_tete(queue fa) {
assert(!queue_est_vide(fa));
return fa.data[0];
}
int queue_debut(queue fa) {
assert(!queue_est_vide(fa));
return fa.data[fa.debut];
}
queue queue_creer() {
queue fa;
fa.capacite = INCR;
fa.debut = -1;
fa.data = malloc(INCR*sizeof(int));
return fa;
}
void queue_resize(queue* fa,int max) {
assert(queue_est_valide(*fa));
if (max > fa->capacite) {
fa->capacite = max;
fa->data = realloc(fa->data,max*sizeof(int));
}
}
void queue_detruire(queue* fa) {
// à compléter
}
void queue_inserer(queue* fa,int val) {
if (queue_est_pleine(*fa)) {
queue_resize(fa,fa->capacite+INCR);
}
fa->debut++;
fa->data[fa->debut] = val;
}
int queue_extraire(queue* fa) {
int val = queue_tete(*fa);
// à compléter
return val;
}
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include "queue_ptr_int.h"
//Creer une nouvelle queue vide
queue queue_creer() {
queue fa;
fa.tete = fa.debut = NULL;
return fa;
}
//Inserer un élement en début de queue
void queue_inserer(queue* fa,int val) {
element* elmt = malloc(sizeof(element));
elmt->data = val;
elmt->next = NULL;
if (queue_est_vide(*fa)) {
fa->tete = elmt;
} else {
fa->debut->next = elmt;
}
fa->debut = elmt;
}
//Extraire un élément en tête de queue
int queue_extraire(queue* fa) {
int val = queue_tete(*fa);
element* elmt = fa->tete;
fa->tete = fa->tete->next;
free(elmt);
if (NULL == fa->tete) {
fa->debut = NULL;
}
return val;
}
//Désallouer complètement la queue
void queue_detruire(queue* fa) {
while (!queue_est_vide(*fa)) {
int val = queue_extraire(fa);
}
}
//Tester si la queue est vide
bool queue_est_vide(queue fa) {
return (NULL == fa.tete && NULL == fa.debut);
}
//Consulter l'élément en tête de queue
int queue_tete(queue fa) {
assert(!queue_est_vide(fa));
return fa.tete->data;
}
//Consulter l'élément en début de queue
int queue_debut(queue fa) {
assert(!queue_est_vide(fa));
return fa.debut->data;
}
//Compter le nombre d'éléments de la queue:
int queue_count(queue fa) {
int cnt = 0;
while (NULL != fa.tete->next) {
fa.tete = fa.tete->next;
cnt++;
}
return cnt;
}
/////////////////////////////////////////////////////////
/*
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "fa.h"
void print(void* a) {
int* b = (int*)a;
printf("%d ",*b);
}
int cmp(void* a,void* b) {
int* aa = (int*)a;
int* bb = (int*)b;
if (*aa == *bb) return 0;
else if (*aa < *bb) return -1;
else return 1;
}
int main() {
fa_Elmt* queue = fa_create();
int a = 3;
queue = fa_push(queue,&a);
int b = 6;
queue = fa_push(queue,&b);
int c = 7;
queue = fa_push(queue,&c);
fa_process(queue,print); printf("\n");
int d = 6;
fa_Elmt* elmt = fa_pop(queue,&d,cmp);
int* tutu = (int*)(elmt->data);
printf("%d\n",*tutu);
fa_process(queue,print); printf("\n");
return 0;
}*/
/* pour éviter que le précompilateur inclue plusieurs fois le fichier .h */
#ifndef QUEUE_PTR_INT_H
#define QUEUE_PTR_INT_H
#include <stdbool.h>
/* Utilité du typedef : Element a; <=> struct Element a; */
typedef struct _element {
int data;
struct _element* next;
} element;
typedef struct _queue {
element* tete;
element* debut;
} queue;
//Créer d'une nouvelle queue vide
queue queue_creer();
//Désallouer complètement la queue
void queue_detruire(queue* fa);
//Insérer un élement en début de queue
void queue_inserer(queue* fa,int val);
//Extraire un élément de la queue
int queue_extraire(queue* fa);
//Consulter l'élément en tête de queue
int queue_tete(queue fa);
//Consulter l'élément en début de queue
int queue_debut(queue fa);
//Tester si la queue est vide
bool queue_est_vide(queue fa);
//Compter le nombre d'éléments de la queue:
int queue_count(queue fa);
#endif
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include "queue_ptr_int.h"
//Creer une nouvelle queue vide
queue queue_creer() {
queue fa;
fa.tete = fa.debut = NULL;
return fa;
}
//Inserer un élement en début de queue
void queue_inserer(queue* fa,int val) {
element* elmt = malloc(sizeof(element));
elmt->data = val;
elmt->next = NULL;
if (queue_est_vide(*fa)) {
fa->tete = elmt;
} else {
fa->debut->next = elmt;
}
fa->debut = elmt;
}
//Extraire un élément en tête de queue
int queue_extraire(queue* fa) {
int val = queue_tete(*fa);
element* elmt = fa->tete;
fa->tete = fa->tete->next;
free(elmt);
if (NULL == fa->tete) {
fa->debut = NULL;
}
return val;
}
//Désallouer complètement la queue
void queue_detruire(queue* fa) {
// à compléter
}
//Tester si la queue est vide
bool queue_est_vide(queue fa) {
return (NULL == fa.tete && NULL == fa.debut);
}
//Consulter l'élément en tête de queue
int queue_tete(queue fa) {
assert(!queue_est_vide(fa));
return fa.tete->data;
}
//Consulter l'élément en début de queue
int queue_debut(queue fa) {
assert(!queue_est_vide(fa));
return fa.debut->data;
}
//Compter le nombre d'éléments de la queue:
int queue_count(queue fa) {
int cnt = 0;
// à compléter
return cnt;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment