/*****************************************/ /* Implémentations des listes de sommets */ /* Utilisation d'un tuyau par liste */ /*****************************************/ #include "type_dequeue.h" #include #include #include #include "error.h" #include "type_boolarray.h" /************************/ /* Fonctions primitives */ /************************/ /* Création */ dequeue *create_dequeue(void) { dequeue *ptr = malloc(sizeof(dequeue)); ptr->array = malloc(sizeof(uint) * 1); ptr->size_array = 1; ptr->left = 0; ptr->right = 0; ptr->empty = true; return ptr; } /* Suppression */ void delete_dequeue(dequeue *ptr) { if (ptr == NULL) ERROR("delete_dequeue : ptr NULL"); if (ptr->array != NULL) free(ptr->array); if (ptr != NULL) free(ptr); ptr = NULL; } /* Test du vide */ bool isempty_dequeue(dequeue *ptr) { if (ptr == NULL) ERROR("isempty_dequeue : ptr NULL"); return ptr->empty; } /* Vidage d'un tuyau*/ void makeempty_dequeue(dequeue *ptr) { if (ptr == NULL) ERROR("makeempty_dequeue : ptr NULL"); if (ptr->array != NULL) free(ptr->array); ptr->array = malloc(sizeof(uint) * 1); ptr->size_array = 1; ptr->left = 0; ptr->right = 0; ptr->empty = true; } /* Taille */ uint size_dequeue(dequeue *ptr) { if (ptr == NULL) ERROR("size_dequeue : ptr NULL"); if (isempty_dequeue(ptr)) return 0; else if (ptr->right > ptr->left) return ptr->right - ptr->left; else if (ptr->right == ptr->left) return ptr->size_array; else return ptr->size_array - ptr->left + ptr->right; } /* Lecture */ uint lefread_dequeue(dequeue *ptr, uint i) { if (ptr == NULL) ERROR("lefread_dequeue : ptr NULL"); if (isempty_dequeue(ptr)) ERROR("lefread_dequeue : ptr empty"); if (i >= size_dequeue(ptr)) ERROR("lefread_dequeue : i out of bounds"); return ptr->array[(ptr->left + i) % ptr->size_array]; } uint rigread_dequeue(dequeue *ptr, uint i) { if (ptr == NULL) ERROR("rigread_dequeue : ptr NULL"); if (isempty_dequeue(ptr)) ERROR("rigread_dequeue : ptr empty"); if (i >= size_dequeue(ptr)) ERROR("rigread_dequeue : i out of bounds"); return ptr->array[(ptr->right - i - 1) % ptr->size_array]; } static void grow_dequeue(dequeue *ptr) { if (ptr == NULL) ERROR("grow_dequeue : ptr NULL"); while (ptr->left != 0) { int temp = ptr->array[ptr->left]; for (uint i = 0; i < ptr->size_array; i++) { ptr->array[(ptr->left + i) % ptr->size_array] = ptr->array[(ptr->left + i + 1) % ptr->size_array]; } ptr->array[(ptr->left - 1) % ptr->size_array] = temp; ptr->left--; ptr->right = (ptr->right - 1) % ptr->size_array; } ptr->right = ptr->size_array; ptr->left = 0; ptr->size_array *= 2; ptr->array = realloc(ptr->array, ptr->size_array * sizeof(int)); return; } /* Insérer */ void lefins_dequeue(uint val, dequeue *ptr) { if (ptr == NULL) ERROR("lefins_dequeue : ptr NULL"); if (ptr->left == ptr->right && !isempty_dequeue(ptr)) { grow_dequeue(ptr); } ptr->left = (ptr->left - 1 + ptr->size_array) % ptr->size_array; ptr->array[ptr->left] = val; ptr->empty = false; return; } void rigins_dequeue(uint val, dequeue *ptr) { if (ptr == NULL) ERROR("rigins_dequeue : ptr NULL"); if (ptr->left == ptr->right && !isempty_dequeue(ptr)) { grow_dequeue(ptr); } ptr->array[ptr->right] = val; ptr->right = (ptr->right + 1) % ptr->size_array; ptr->empty = false; return; } static void shrink_dequeue(dequeue *ptr) { if (ptr == NULL) ERROR("shrink_dequeue : ptr NULL"); uint *aux = malloc((ptr->size_array / 2) * sizeof(uint)); for (uint i = 0; i < size_dequeue(ptr); i++) { aux[i] = ptr->array[(ptr->left + i) % ptr->size_array]; } free(ptr->array); ptr->array = aux; ptr->left = 0; ptr->size_array = ptr->size_array / 2; ptr->right = size_dequeue(ptr); return; } /* Retirer */ uint lefpull_dequeue(dequeue *ptr) { if (ptr == NULL) ERROR("lefpull_dequeue : ptr NULL"); if (isempty_dequeue(ptr)) ERROR("lefpull_dequeue : ptr empty"); int val = ptr->array[ptr->left]; ptr->left = (ptr->left + 1) % ptr->size_array; if (size_dequeue(ptr) <= ptr->size_array / 4 && ptr->size_array > 1) { shrink_dequeue(ptr); } if (ptr->left == ptr->right) ptr->empty = true; return val; } uint rigpull_dequeue(dequeue *ptr) { if (ptr == NULL) ERROR("rigpull_dequeue : ptr NULL"); if (isempty_dequeue(ptr)) ERROR("rigpull_dequeue : ptr empty"); ptr->right = (ptr->right - 1) % ptr->size_array; int val = ptr->array[ptr->right]; if (size_dequeue(ptr) <= ptr->size_array / 4 && ptr->size_array > 1) { shrink_dequeue(ptr); } if (ptr->left == ptr->right) ptr->empty = true; return val; } /* Création d'une copie avec décalage */ void copy_dequeue_right(dequeue *ptr1, dequeue *ptr2, uint val) { if (ptr1 == NULL || ptr2 == NULL) ERROR("copy_dequeue_right : ptr NULL"); if (isempty_dequeue(ptr2)) ERROR("copy_dequeue_right : ptr2 empty"); for (uint i = 0; i < size_dequeue(ptr2); i++) { lefread_dequeue(ptr2, i); rigins_dequeue(lefread_dequeue(ptr2, i) + val, ptr1); } return; } /* Teste si un élément appartient à une dequeue*/ bool mem_dequeue(uint val, dequeue *ptr) { if (ptr == NULL) ERROR("mem_dequeue : ptr NULL"); for (uint i = 0; i < size_dequeue(ptr); i++) { if (val == lefread_dequeue(ptr, i)) return true; } return false; } /* Affichage */ void print_dequeue(dequeue *ptr) { if (ptr == NULL) ERROR("print_dequeue : ptr NULL"); printf("Deque : "); for (uint i = 0; i < size_dequeue(ptr); i++) { printf("%d ", lefread_dequeue(ptr, i)); } printf("\n"); return; } /* Tri par ordre croissant et suppression des doublons */ void sort_dequeue_norepeat(dequeue *ptr) { if (ptr == NULL) ERROR("sort_dequeue_norepeat : ptr NULL"); if (isempty_dequeue(ptr)) return; if (size_dequeue(ptr) == 1) return; for (uint i = 0; i < size_dequeue(ptr); i++) { for (uint j = i + 1; j < size_dequeue(ptr); j++) { if (lefread_dequeue(ptr, i) > lefread_dequeue(ptr, j)) { int temp = lefread_dequeue(ptr, i); ptr->array[(ptr->left + i) % ptr->size_array] = lefread_dequeue(ptr, j); ptr->array[(ptr->left + j) % ptr->size_array] = temp; } } } uint i; for (i = 0; i < size_dequeue(ptr) && lefread_dequeue(ptr, i) != rigread_dequeue(ptr, 0); i++) { uint count = 0; while (i + count < size_dequeue(ptr) && lefread_dequeue(ptr, i) == lefread_dequeue(ptr, i + count)) { count++; } for (uint j = 1; j < count; j++) { for (uint k = i; k < size_dequeue(ptr) - 1; k++) { ptr->array[(ptr->left + k) % ptr->size_array] = lefread_dequeue(ptr, k + 1); } } } ptr->right = (ptr->right - (size_dequeue(ptr) - i - 1)) % ptr->size_array; return; } /*****************************************************************/ /* Fonctions spécifiques aux ensembles triés par ordre croissant */ /*****************************************************************/ bool mem_dequeue_sorted(uint val, dequeue *ptr) { if (ptr == NULL) ERROR("mem_dequeue_sorted : ptr NULL"); if (isempty_dequeue(ptr)) return false; int left = 0; int right = size_dequeue(ptr) - 1; while (left <= right) { int mid = (left + right) / 2; if (lefread_dequeue(ptr, mid) == val) return true; if (lefread_dequeue(ptr, mid) < val) { left = mid + 1; } else { right = mid - 1; } } return false; } void merge_sorted_dequeue(dequeue *ptr1, dequeue *ptr2) { if (ptr1 == NULL || ptr2 == NULL) ERROR("merge_sorted_dequeue : ptr NULL"); if (isempty_dequeue(ptr2)) return; if (isempty_dequeue(ptr1)) { copy_dequeue_right(ptr1, ptr2, 0); return; } uint i = 0; uint j = 0; dequeue *temp = create_dequeue(); while (i < size_dequeue(ptr1) && j < size_dequeue(ptr2)) { if (lefread_dequeue(ptr1, i) <= lefread_dequeue(ptr2, j)) { rigins_dequeue(lefread_dequeue(ptr1, i), temp); i++; } else { rigins_dequeue(lefread_dequeue(ptr2, j), temp); j++; } } while (i < size_dequeue(ptr1)) { rigins_dequeue(lefread_dequeue(ptr1, i), temp); i++; } while (j < size_dequeue(ptr2)) { rigins_dequeue(lefread_dequeue(ptr2, j), temp); j++; } makeempty_dequeue(ptr1); copy_dequeue_right(ptr1, temp, 0); if (temp == NULL) delete_dequeue(temp); for (i = 0; i < size_dequeue(ptr1) && lefread_dequeue(ptr1, i) != rigread_dequeue(ptr1, 0); i++) { uint count = 0; while (i + count < size_dequeue(ptr1) && lefread_dequeue(ptr1, i) == lefread_dequeue(ptr1, i + count)) { count++; } for (j = 1; j < count; j++) { for (uint k = i; k < size_dequeue(ptr1) - 1; k++) { ptr1->array[(ptr1->left + k) % ptr1->size_array] = lefread_dequeue(ptr1, k + 1); } } } ptr1->right = (ptr1->right - (size_dequeue(ptr1) - i - 1)) % ptr1->size_array; return; } dequeue *make_inter_sorted_dequeue(dequeue *ptr1, dequeue *ptr2) { if (ptr1 == NULL || ptr2 == NULL) ERROR("make_inter_sorted_dequeue : ptr NULL"); dequeue *ptr = create_dequeue(); for (uint i = 0; i < size_dequeue(ptr1); i++) { if (mem_dequeue_sorted(lefread_dequeue(ptr1, i), ptr2)) { rigins_dequeue(lefread_dequeue(ptr1, i), ptr); } } return ptr; } /* Insére un nouveau sommet dans une liste */ void insert_dequeue(dequeue *ptr, uint val) { if (ptr == NULL) ERROR("insert_dequeue : ptr NULL"); if (mem_dequeue_sorted(val, ptr)) return; dequeue *temp = create_dequeue(); rigins_dequeue(val, temp); merge_sorted_dequeue(ptr, temp); } /* Teste si deux dequeues triées s'intersectent */ bool intersec_dequeue(dequeue *ptr1, dequeue *ptr2) { if (ptr1 == NULL || ptr2 == NULL) ERROR("intersec_dequeue : ptr NULL"); if (isempty_dequeue(ptr1) || isempty_dequeue(ptr2)) return false; for (uint i = 0; i < size_dequeue(ptr1); i++) { if (mem_dequeue_sorted(lefread_dequeue(ptr1, i), ptr2)) { return true; } } return false; }