Renommage name -> value, frequency -> count dans HufTree

Initialisation de value à -1 lorsque aucune valeur
This commit is contained in:
Mattéo Delabre 2016-11-20 15:57:15 +01:00
parent fdbdeb1756
commit e915bd3080
4 changed files with 30 additions and 23 deletions

View File

@ -16,15 +16,13 @@ typedef struct ReadBuffer ReadBuffer;
typedef struct HufVertex HufVertex; typedef struct HufVertex HufVertex;
typedef HufVertex* HufTree; typedef HufVertex* HufTree;
struct HufVertex { struct HufVertex {
// Indique la fréquence d'apparition de la lettre du sommet // Caractère associé à ce sommet ou -1 s'il n'y a aucun caractère
// dans le corpus original, ou bien la somme des fréquences // associé (notamment s'il s'agit d'une branche)
// de ses enfants (si ce n'est pas une feuille) unsigned int value;
double frequency;
// Caractère du corpus original associé à ce sommet. Uniquement // Indique l'effectif du caractère associée à ce sommet
// valable pour les feuilles. Pour les autres sommets, la valeur // dans le fichier source, ou -1 s'il n'y a aucun caractère associé
// de `name` n'est pas garantie bytecount count;
int name;
// Pointeurs vers les deux enfants de ce sommet. Ils valent tous // Pointeurs vers les deux enfants de ce sommet. Ils valent tous
// deux NULL si le sommet est une feuille. À noter qu'un sommet // deux NULL si le sommet est une feuille. À noter qu'un sommet

View File

@ -12,6 +12,11 @@ void decompress(FILE* source, FILE* dest) {
fread(&original_count, sizeof(original_count), 1, source); fread(&original_count, sizeof(original_count), 1, source);
printVerbose("Lecture du nombre de caractères : %d.\n", original_count); printVerbose("Lecture du nombre de caractères : %d.\n", original_count);
if (original_count == 0) {
// Cas particulier : fichier vide, rien à restituer
return;
}
// ÉTAPE 2 : reconstruction de l'arbre à partir des données linéarisées // ÉTAPE 2 : reconstruction de l'arbre à partir des données linéarisées
printVerbose("Reconstruction de l'arbre de Huffman.\n"); printVerbose("Reconstruction de l'arbre de Huffman.\n");
ReadBuffer input = createReadBuffer(source); ReadBuffer input = createReadBuffer(source);
@ -48,7 +53,7 @@ void decompress(FILE* source, FILE* dest) {
// La valeur de la feuille trouvée est le caractère compressé : // La valeur de la feuille trouvée est le caractère compressé :
// on l'écrit dans le fichier // on l'écrit dans le fichier
fputc(current->name, dest); fputc(current->value, dest);
wrote_count++; wrote_count++;
} }

View File

@ -85,7 +85,7 @@ void _subPrintTree(HufTree tree, wchar_t* buffer, int length) {
} else { } else {
// Affichage d'une feuille de l'arbre, correspondant // Affichage d'une feuille de l'arbre, correspondant
// à un caractère du corpus // à un caractère du corpus
printVerbose("%c\n", _safeChar(tree->name)); printVerbose("%c\n", _safeChar(tree->value));
} }
} }

View File

@ -48,8 +48,8 @@ HufTree createTree(bytecount* counts) {
if (counts[i] > 0) { if (counts[i] > 0) {
remaining[next_index] = malloc(sizeof(*remaining[next_index])); remaining[next_index] = malloc(sizeof(*remaining[next_index]));
remaining[next_index]->name = i; remaining[next_index]->value = i;
remaining[next_index]->frequency = counts[i]; remaining[next_index]->count = counts[i];
remaining[next_index]->child_l = NULL; remaining[next_index]->child_l = NULL;
remaining[next_index]->child_r = NULL; remaining[next_index]->child_r = NULL;
@ -80,7 +80,8 @@ HufTree createTree(bytecount* counts) {
// Création d'un sommet parent P pour A et B // Création d'un sommet parent P pour A et B
HufVertex* parent = malloc(sizeof(*parent)); HufVertex* parent = malloc(sizeof(*parent));
parent->frequency = min_vert->frequency + sec_min_vert->frequency; parent->value = -1;
parent->count = min_vert->count + sec_min_vert->count;
parent->child_l = min_vert; parent->child_l = min_vert;
parent->child_r = sec_min_vert; parent->child_r = sec_min_vert;
@ -118,8 +119,8 @@ void _findMinimalVertices(
size_t* min_index, size_t* sec_min_index size_t* min_index, size_t* sec_min_index
) { ) {
// Initialisation de telle sorte qu'initialement // Initialisation de telle sorte qu'initialement
// on ait `freq(min_index) < freq(sec_min_index)` // on ait `count(min_index) < count(sec_min_index)`
if (vertices[0]->frequency < vertices[1]->frequency) { if (vertices[0]->count < vertices[1]->count) {
*min_index = 0; *min_index = 0;
*sec_min_index = 1; *sec_min_index = 1;
} else { } else {
@ -128,14 +129,14 @@ void _findMinimalVertices(
} }
for (size_t i = 2; i < size; i++) { for (size_t i = 2; i < size; i++) {
double freq = vertices[i]->frequency; double freq = vertices[i]->count;
if (freq < vertices[*min_index]->frequency) { if (freq < vertices[*min_index]->count) {
// Sommet de valeur inférieure au minimum trouvé, la valeur // Sommet de valeur inférieure au minimum trouvé, la valeur
// devient le nouveau minimum, le minimum devient second minimum // devient le nouveau minimum, le minimum devient second minimum
*sec_min_index = *min_index; *sec_min_index = *min_index;
*min_index = i; *min_index = i;
} else if (freq < vertices[*sec_min_index]->frequency) { } else if (freq < vertices[*sec_min_index]->count) {
// Sommet de valeur entre le minimum et le second minimum trouvé, // Sommet de valeur entre le minimum et le second minimum trouvé,
// la valeur devient le nouveau second minimum // la valeur devient le nouveau second minimum
*sec_min_index = i; *sec_min_index = i;
@ -163,7 +164,7 @@ void writeTree(HufTree tree, WriteBuffer* buffer) {
// Écriture de la valeur du sommet // Écriture de la valeur du sommet
for (int i = 7; i >= 0; i--) { for (int i = 7; i >= 0; i--) {
putBuffer((tree->name & (1 << i)) != 0, buffer); putBuffer((tree->value & (1 << i)) != 0, buffer);
} }
} }
} }
@ -176,17 +177,20 @@ HufTree readTree(ReadBuffer* buffer) {
if (bit == 1) { if (bit == 1) {
// Sommet avec enfants // Sommet avec enfants
tree->value = -1;
tree->count = -1;
tree->child_l = readTree(buffer); tree->child_l = readTree(buffer);
tree->child_r = readTree(buffer); tree->child_r = readTree(buffer);
} else if (bit == 0) { } else if (bit == 0) {
// Feuille de l'arbre // Feuille de l'arbre
int name = 0; int value = 0;
for (int i = 7; i >= 0; i--) { for (int i = 7; i >= 0; i--) {
name |= getBuffer(buffer) << i; value |= getBuffer(buffer) << i;
} }
tree->name = name; tree->value = value;
tree->count = 0;
tree->child_l = NULL; tree->child_l = NULL;
tree->child_r = NULL; tree->child_r = NULL;
} }
@ -241,7 +245,7 @@ void _labelVertex(HufVertex vertex, char** labels, char* label, size_t length) {
} else { } else {
// Si le sommet est une feuille, étiquetage du caractère // Si le sommet est une feuille, étiquetage du caractère
// associé avec l'étiquette passée en paramètre. Fin de la récursion // associé avec l'étiquette passée en paramètre. Fin de la récursion
labels[vertex.name] = label; labels[vertex.value] = label;
} }
} }