Renommage name -> value, frequency -> count dans HufTree
Initialisation de value à -1 lorsque aucune valeur
This commit is contained in:
parent
fdbdeb1756
commit
e915bd3080
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue