Modification du type HufTree et implémentation lecture arbre
Utilisation de WriteBuffer et ReadBuffer et le type HufTree n'est plus une structure mais un typedef vers HufVertex*
This commit is contained in:
parent
e19860e544
commit
9576b371ce
|
@ -4,12 +4,15 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef struct Buffer Buffer;
|
typedef struct WriteBuffer WriteBuffer;
|
||||||
|
typedef struct ReadBuffer ReadBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Représente un des sommets d'un arbre de Huffman
|
* Représente un des sommets d'un arbre de Huffman (représente l'arbre
|
||||||
|
* en entier s'il s'agit de la racine)
|
||||||
*/
|
*/
|
||||||
typedef struct HufVertex HufVertex;
|
typedef struct HufVertex HufVertex;
|
||||||
|
typedef HufVertex* HufTree;
|
||||||
struct HufVertex {
|
struct HufVertex {
|
||||||
// Indique la fréquence d'apparition de la lettre du sommet
|
// Indique la fréquence d'apparition de la lettre du sommet
|
||||||
// dans le corpus original, ou bien la somme des fréquences
|
// dans le corpus original, ou bien la somme des fréquences
|
||||||
|
@ -28,18 +31,6 @@ struct HufVertex {
|
||||||
HufVertex* child_r;
|
HufVertex* child_r;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Représente un arbre de Huffman
|
|
||||||
*/
|
|
||||||
typedef struct HufTree HufTree;
|
|
||||||
struct HufTree {
|
|
||||||
// Pointeur sur la racine de l'arbre
|
|
||||||
HufVertex* root;
|
|
||||||
|
|
||||||
// Quantité de sommets dans l'arbre
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construire un arbre de Huffman basé sur les fréquences
|
* Construire un arbre de Huffman basé sur les fréquences
|
||||||
* de caractères passées dans `frequencies`
|
* de caractères passées dans `frequencies`
|
||||||
|
@ -52,13 +43,13 @@ HufTree createTree(double* frequencies);
|
||||||
* Écrit une représentation binaire de l'arbre dans le
|
* Écrit une représentation binaire de l'arbre dans le
|
||||||
* tampon passé en paramètre
|
* tampon passé en paramètre
|
||||||
*/
|
*/
|
||||||
void writeTree(HufTree, Buffer*);
|
void writeTree(HufTree, WriteBuffer*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconstruit un arbre de Huffman à partir du fichier passé
|
* Reconstruit un arbre de Huffman à partir du fichier passé
|
||||||
* en paramètre
|
* en paramètre
|
||||||
*/
|
*/
|
||||||
HufTree readTree(FILE*);
|
HufTree readTree(ReadBuffer*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Libérer la mémoire occupée par un arbre de Huffman
|
* Libérer la mémoire occupée par un arbre de Huffman
|
||||||
|
|
102
src/huftree.c
102
src/huftree.c
|
@ -12,18 +12,6 @@
|
||||||
*/
|
*/
|
||||||
static void _findMinimalVertices(HufVertex**, size_t, size_t* min, size_t* sec);
|
static void _findMinimalVertices(HufVertex**, size_t, size_t* min, size_t* sec);
|
||||||
|
|
||||||
/**
|
|
||||||
* Écrit dans le tampon donné les informations sur le sommet
|
|
||||||
* en question et tous ses fils
|
|
||||||
*/
|
|
||||||
static void _writeVertex(HufVertex, Buffer*);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Libérer récursivement la mémoire occupée par le sommet
|
|
||||||
* donné ainsi que celle de tous ses enfants (s'il en a).
|
|
||||||
*/
|
|
||||||
static void _freeTreeVertex(HufVertex*);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Créer une nouvelle chaîne contenant la chaîne donnée
|
* Créer une nouvelle chaîne contenant la chaîne donnée
|
||||||
* suffixée du caractère donné
|
* suffixée du caractère donné
|
||||||
|
@ -105,14 +93,9 @@ HufTree createTree(double* frequencies) {
|
||||||
remaining_count--;
|
remaining_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stockage de l'adresse vers la racine de l'arbre dans un HufTree.
|
|
||||||
// Il est désormais possible de désallouer `remaining`, car la seule
|
// Il est désormais possible de désallouer `remaining`, car la seule
|
||||||
// connaissance de la racine permet de parcourir tout l'arbre
|
// connaissance de la racine permet de parcourir tout l'arbre
|
||||||
HufTree tree = {
|
HufTree tree = remaining[0];
|
||||||
.root = remaining[0],
|
|
||||||
.size = 2 * leaves_count - 1
|
|
||||||
};
|
|
||||||
|
|
||||||
free(remaining);
|
free(remaining);
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
@ -147,66 +130,55 @@ void _findMinimalVertices(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeTree(HufTree tree, Buffer* buffer) {
|
void writeTree(HufTree tree, WriteBuffer* buffer) {
|
||||||
_writeVertex(*tree.root, buffer);
|
if (tree->child_l != NULL && tree->child_r != NULL) {
|
||||||
}
|
// Bit "1" indiquant que le sommet a des enfants
|
||||||
|
putBuffer(1, buffer);
|
||||||
void _writeVertex(HufVertex vertex, Buffer* buffer) {
|
|
||||||
if (vertex.child_l != NULL && vertex.child_r != NULL) {
|
|
||||||
// Séquence de 9 bits indiquant un sommet qui
|
|
||||||
// n'est pas une feuille (100000000)
|
|
||||||
pushToBuffer(1, buffer);
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
pushToBuffer(0, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Écriture du fils gauche et du fils droit
|
// Écriture du fils gauche et du fils droit
|
||||||
_writeVertex(*vertex.child_l, buffer);
|
writeTree(tree->child_l, buffer);
|
||||||
_writeVertex(*vertex.child_r, buffer);
|
writeTree(tree->child_r, buffer);
|
||||||
} else {
|
} else {
|
||||||
// Séquence de 9 bits encodant la feuille rencontrée
|
// Bit "0" indiquant que le sommet n'a pas d'enfants
|
||||||
// (0 + octet du caractère)
|
putBuffer(0, buffer);
|
||||||
pushToBuffer(0, buffer);
|
|
||||||
|
|
||||||
|
// Écriture de la valeur du sommet
|
||||||
for (int i = 7; i >= 0; i--) {
|
for (int i = 7; i >= 0; i--) {
|
||||||
pushToBuffer(
|
putBuffer((tree->name & (1 << i)) != 0, buffer);
|
||||||
// Écriture du n-ième bit du caractère du fils
|
|
||||||
// dans le tampon
|
|
||||||
(vertex.name & (1 << i)) != 0,
|
|
||||||
buffer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Séquence de 9 bits indiquant un sommet
|
|
||||||
// sans fils (100000001)
|
|
||||||
pushToBuffer(1, buffer);
|
|
||||||
|
|
||||||
for (int i = 0; i < 7; i++) {
|
|
||||||
pushToBuffer(0, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
pushToBuffer(1, buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HufTree readTree(FILE* output) {
|
HufTree readTree(ReadBuffer* buffer) {
|
||||||
// TODO: implémenter la lecture des arbres
|
HufTree tree = malloc(sizeof(*tree));
|
||||||
exit(0);
|
|
||||||
|
if (getBuffer(buffer) == 1) {
|
||||||
|
// Sommet avec enfants
|
||||||
|
tree->child_l = readTree(buffer);
|
||||||
|
tree->child_r = readTree(buffer);
|
||||||
|
} else {
|
||||||
|
// Feuille de l'arbre
|
||||||
|
int name = 0;
|
||||||
|
|
||||||
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
name |= getBuffer(buffer) << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree->name = name;
|
||||||
|
tree->child_l = NULL;
|
||||||
|
tree->child_r = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeTree(HufTree tree) {
|
void freeTree(HufTree tree) {
|
||||||
_freeTreeVertex(tree.root);
|
if (tree->child_l != NULL && tree->child_r != NULL) {
|
||||||
tree.root = NULL;
|
freeTree(tree->child_l);
|
||||||
}
|
freeTree(tree->child_r);
|
||||||
|
|
||||||
void _freeTreeVertex(HufVertex* vert) {
|
|
||||||
if (vert->child_l != NULL && vert->child_r != NULL) {
|
|
||||||
_freeTreeVertex(vert->child_l);
|
|
||||||
_freeTreeVertex(vert->child_r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(vert);
|
free(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
char** createTreeLabels(HufTree input) {
|
char** createTreeLabels(HufTree input) {
|
||||||
|
@ -217,7 +189,7 @@ char** createTreeLabels(HufTree input) {
|
||||||
labels[i] = NULL;
|
labels[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
_labelVertex(*input.root, labels, NULL, 0);
|
_labelVertex(*input, labels, NULL, 0);
|
||||||
return labels;
|
return labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue