update tp-huffman
This commit is contained in:
138
tp-huffman/binheap.c
Normal file
138
tp-huffman/binheap.c
Normal file
@@ -0,0 +1,138 @@
|
||||
#include "binheap.h"
|
||||
|
||||
/*************************/
|
||||
/* Fonctions auxiliaires */
|
||||
/*************************/
|
||||
|
||||
/* La fonction de comparaison pour les tas d'entiers */
|
||||
bool fcmp_int(void *x, void *y) {
|
||||
return *(int *)x < *(int *)y;
|
||||
}
|
||||
|
||||
/* Fonctions de navigation dans un arbre représenté par un tableau */
|
||||
int left_binheap(int i) {
|
||||
return i*2+1;
|
||||
}
|
||||
int right_binheap(int i) {
|
||||
return i*2+2;
|
||||
}
|
||||
int parent_binheap(int i) {
|
||||
return (i-1)/2;
|
||||
}
|
||||
bool isvalid_binheap(binheap *p, int i) {
|
||||
return i < p->size_heap;
|
||||
}
|
||||
|
||||
/* Modification de la taille du tableau */
|
||||
static void grow_binheap(binheap *p) {
|
||||
p->size_array *= 2;
|
||||
p->array = realloc(p->array, p->size_array * sizeof(void *));
|
||||
if (p->array == NULL) {
|
||||
ERROR("Erreur d'allocation mémoire\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static void shrink_binheap(binheap *p) {
|
||||
p->size_array /= 2;
|
||||
p->array = realloc(p->array, p->size_array * sizeof(void *));
|
||||
if (p->array == NULL) {
|
||||
ERROR("Erreur d'allocation mémoire\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/************************/
|
||||
/* Fonctions primitives */
|
||||
/************************/
|
||||
|
||||
/* Création d'un tas vide */
|
||||
binheap *create_binheap(bool (*fc)(void *, void *)) {
|
||||
binheap *p = malloc(sizeof(binheap));
|
||||
if (p == NULL) {
|
||||
ERROR("Erreur d'allocation mémoire\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
p->array = malloc(1 * sizeof(void *));
|
||||
if (p->array == NULL) {
|
||||
ERROR("Erreur d'allocation mémoire\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
p->size_array = 1;
|
||||
p->size_heap = 0;
|
||||
p->fc = fc;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Suppression */
|
||||
void delete_binheap(binheap *p) {
|
||||
if (p != NULL) {
|
||||
if (p->array != NULL) {
|
||||
free(p->array);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test du vide */
|
||||
bool isempty_binheap(binheap *p) {
|
||||
return p == NULL || p->size_heap == 0;
|
||||
}
|
||||
|
||||
/* Récupération de la taille */
|
||||
int getsize_binheap(binheap *p) {
|
||||
return p->size_heap;
|
||||
}
|
||||
|
||||
/* Insertion d'une valeur */
|
||||
void push_binheap(binheap *p, void *val) {
|
||||
if (p->size_heap == p->size_array) {
|
||||
grow_binheap(p);
|
||||
}
|
||||
p->array[p->size_heap] = val;
|
||||
p->size_heap++;
|
||||
int i = p->size_heap - 1;
|
||||
while (i > 0 && p->fc(p->array[i], p->array[parent_binheap(i)])) {
|
||||
void *temp = p->array[i];
|
||||
p->array[i] = p->array[parent_binheap(i)];
|
||||
p->array[parent_binheap(i)] = temp;
|
||||
i = parent_binheap(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Récupération du minimum sans le retirer */
|
||||
void *peekmin_binheap(binheap *p) {
|
||||
if (isempty_binheap(p)) {
|
||||
return NULL;
|
||||
}
|
||||
return p->array[0];
|
||||
}
|
||||
|
||||
/* Récupération du minimum en le retirant */
|
||||
void *popmin_binheap(binheap *p) {
|
||||
if (isempty_binheap(p)) {
|
||||
return NULL;
|
||||
}
|
||||
void *min = p->array[0];
|
||||
p->size_heap--;
|
||||
p->array[0] = p->array[p->size_heap];
|
||||
int i = 0;
|
||||
while (isvalid_binheap(p, left_binheap(i))) {
|
||||
int j = left_binheap(i);
|
||||
if (isvalid_binheap(p, right_binheap(i)) && p->fc(p->array[right_binheap(i)], p->array[j])) {
|
||||
j = right_binheap(i);
|
||||
}
|
||||
if (p->fc(p->array[j], p->array[i])) {
|
||||
void *temp = p->array[i];
|
||||
p->array[i] = p->array[j];
|
||||
p->array[j] = temp;
|
||||
i = j;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p->size_heap < p->size_array / 4) {
|
||||
shrink_binheap(p);
|
||||
}
|
||||
return min;
|
||||
}
|
||||
Reference in New Issue
Block a user