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 HufVertex* HufTree;
struct HufVertex {
// Indique la fréquence d'apparition de la lettre du sommet
// dans le corpus original, ou bien la somme des fréquences
// de ses enfants (si ce n'est pas une feuille)
double frequency;
// Caractère associé à ce sommet ou -1 s'il n'y a aucun caractère
// associé (notamment s'il s'agit d'une branche)
unsigned int value;
// Caractère du corpus original associé à ce sommet. Uniquement
// valable pour les feuilles. Pour les autres sommets, la valeur
// de `name` n'est pas garantie
int name;
// Indique l'effectif du caractère associée à ce sommet
// dans le fichier source, ou -1 s'il n'y a aucun caractère associé
bytecount count;
// Pointeurs vers les deux enfants de ce sommet. Ils valent tous
// 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);
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
printVerbose("Reconstruction de l'arbre de Huffman.\n");
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é :
// on l'écrit dans le fichier
fputc(current->name, dest);
fputc(current->value, dest);
wrote_count++;
}

View File

@ -85,7 +85,7 @@ void _subPrintTree(HufTree tree, wchar_t* buffer, int length) {
} else {
// Affichage d'une feuille de l'arbre, correspondant
// à 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) {
remaining[next_index] = malloc(sizeof(*remaining[next_index]));
remaining[next_index]->name = i;
remaining[next_index]->frequency = counts[i];
remaining[next_index]->value = i;
remaining[next_index]->count = counts[i];
remaining[next_index]->child_l = 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
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_r = sec_min_vert;
@ -118,8 +119,8 @@ void _findMinimalVertices(
size_t* min_index, size_t* sec_min_index
) {
// Initialisation de telle sorte qu'initialement
// on ait `freq(min_index) < freq(sec_min_index)`
if (vertices[0]->frequency < vertices[1]->frequency) {
// on ait `count(min_index) < count(sec_min_index)`
if (vertices[0]->count < vertices[1]->count) {
*min_index = 0;
*sec_min_index = 1;
} else {
@ -128,14 +129,14 @@ void _findMinimalVertices(
}
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
// devient le nouveau minimum, le minimum devient second minimum
*sec_min_index = *min_index;
*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é,
// la valeur devient le nouveau second minimum
*sec_min_index = i;
@ -163,7 +164,7 @@ void writeTree(HufTree tree, WriteBuffer* buffer) {
// Écriture de la valeur du sommet
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) {
// Sommet avec enfants
tree->value = -1;
tree->count = -1;
tree->child_l = readTree(buffer);
tree->child_r = readTree(buffer);
} else if (bit == 0) {
// Feuille de l'arbre
int name = 0;
int value = 0;
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_r = NULL;
}
@ -241,7 +245,7 @@ void _labelVertex(HufVertex vertex, char** labels, char* label, size_t length) {
} else {
// Si le sommet est une feuille, étiquetage du caractère
// associé avec l'étiquette passée en paramètre. Fin de la récursion
labels[vertex.name] = label;
labels[vertex.value] = label;
}
}