#include "queue.h" #include "alloc.h" #include "testprint.h" #include #include #include ///////////////////////////////////////////////////////////////////////////////// // 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) { // print_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; } // printf("left = %d, right = %d size = %d\n", p -> left, p -> right, getsize_queue(p)); if (p -> left == p -> right + 1) { p -> empty = true; } return val; }