Files
prog-c/tp3/TP3/queue.c

126 lines
3.8 KiB
C

#include "queue.h"
#include "alloc.h"
#include "testprint.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
/////////////////////////////////////////////////////////////////////////////////
// Fonctions auxiliaires ne pouvant pas être utilisées dans d'autres fichiers. //
// Elles ne sont pas déclarées dans queue.h et sont déclarées "static". Cela //
// signifie qu'elles ne peuvent être utilisées QUE dans ce fichier, queue.c. //
/////////////////////////////////////////////////////////////////////////////////
// Double la taille du tableau utilisé dans la représentation.
// Cette fonction sera utilisée lorsque le tableau est plein et qu'on veut y
// ajouter une valeur.
static void grow_queue(queue *p) {
while (p -> left != 0) {
int temp = p -> array[p -> left];
for (int j = 0; j < p -> size_array; j++) {
p -> array[(p -> left + j) % p -> size_array] = p -> array[(p -> left + j + 1) % p -> size_array];
}
p -> array[(p -> left - 1) % p -> size_array] = temp;
p -> left--;
p -> right = (p -> right - 1) % p -> size_array;
}
p -> right = p -> size_array;
p -> left = 0;
p -> size_array *= 2;
p -> array = realloc(p -> array, p -> size_array * sizeof(int));
return;
}
// Divise par deux la taille du tableau utilisé dans la représentation
// Cette fonction sera utilisée lorsque le tableau est rempli à moins de 25% de
// sa capacité.
static void shrink_queue(queue *p) {
if (p -> size_array >= 2) {
while (p -> left != 0) {
int temp = p -> array[p -> left];
for (int j = 0; j < p -> size_array; j++) {
p -> array[(p -> left + j) % p -> size_array] = p -> array[(p -> left + j + 1) % p -> size_array];
}
p -> array[(p -> left - 1) % p -> size_array] = temp;
p -> left--;
p -> right = (p -> right - 1) % p -> size_array;
}
p -> size_array /= 2;
p -> array = realloc(p -> array, p -> size_array * sizeof(int));
}
return;
}
////////////////////////////////////////////////////////////////
// Fonctions primitives, exportées dans le fichier d'en-tête. //
////////////////////////////////////////////////////////////////
queue *create_queue(void) {
queue *p = malloc(sizeof(queue));
p -> size_array = 1;
p -> left = 0;
p -> right = 0;
p -> array = malloc(sizeof(int));
p -> empty = true;
return p;
}
void delete_queue(queue *p) {
if (p == NULL) return;
p -> size_array = 0;
p -> left = 0;
p -> right = 0;
p -> empty = true;
free(p -> array);
free(p);
return;
}
bool isempty_queue(const queue *p) {
return p -> empty;
}
int getsize_queue(const queue *p) {
if (isempty_queue(p)) return 0;
else if (p -> right > p -> left) return p -> right - p -> left;
else if (p -> right == p -> left) return p -> size_array;
else return p -> size_array - (p -> left - p -> right);
}
void enqueue(int val, queue *p) {
if (p -> left == p -> right && !isempty_queue(p)) {
grow_queue(p);
}
p -> left--;
if (p -> left < 0) {
p -> left += p -> size_array;
}
p -> array[p -> left] = val;
p -> empty = false;
return;
}
int dequeue(queue *p) {
if (isempty_queue(p)) {
FATAL("Pop on empty queue");
}
p -> right--;
if (p -> right < 0) {
p -> right += p -> size_array;
}
int val = p -> array[p -> right];
if (getsize_queue(p) <= p -> size_array / 4 && p -> size_array > 1) {
shrink_queue(p);
} else if (getsize_queue(p) <= p -> size_array / 4) {
p -> empty = true;
val = p -> array[p -> left];
p -> left = 0;
p -> right = 0;
return val;
}
if (p -> left == p -> right + 1) {
p -> empty = true;
}
return val;
}