From 9576b371ce1c0224d6975bb3f6ccda734f7089a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre=20=E2=9C=8F?= Date: Sat, 19 Nov 2016 21:38:56 +0100 Subject: [PATCH] =?UTF-8?q?Modification=20du=20type=20HufTree=20et=20impl?= =?UTF-8?q?=C3=A9mentation=20lecture=20arbre?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Utilisation de WriteBuffer et ReadBuffer et le type HufTree n'est plus une structure mais un typedef vers HufVertex* --- inc/huftree.h | 23 ++++-------- src/huftree.c | 102 ++++++++++++++++++-------------------------------- 2 files changed, 44 insertions(+), 81 deletions(-) diff --git a/inc/huftree.h b/inc/huftree.h index ff14644..9dd4f59 100644 --- a/inc/huftree.h +++ b/inc/huftree.h @@ -4,12 +4,15 @@ #include #include -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 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 @@ -28,18 +31,6 @@ struct HufVertex { 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 * 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 * tampon passé en paramètre */ -void writeTree(HufTree, Buffer*); +void writeTree(HufTree, WriteBuffer*); /** * Reconstruit un arbre de Huffman à partir du fichier passé * en paramètre */ -HufTree readTree(FILE*); +HufTree readTree(ReadBuffer*); /** * Libérer la mémoire occupée par un arbre de Huffman diff --git a/src/huftree.c b/src/huftree.c index de0430c..77bfcfc 100644 --- a/src/huftree.c +++ b/src/huftree.c @@ -12,18 +12,6 @@ */ 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 * suffixée du caractère donné @@ -105,14 +93,9 @@ HufTree createTree(double* frequencies) { 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 // connaissance de la racine permet de parcourir tout l'arbre - HufTree tree = { - .root = remaining[0], - .size = 2 * leaves_count - 1 - }; - + HufTree tree = remaining[0]; free(remaining); return tree; } @@ -147,66 +130,55 @@ void _findMinimalVertices( } } -void writeTree(HufTree tree, Buffer* buffer) { - _writeVertex(*tree.root, 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); - } +void writeTree(HufTree tree, WriteBuffer* buffer) { + if (tree->child_l != NULL && tree->child_r != NULL) { + // Bit "1" indiquant que le sommet a des enfants + putBuffer(1, buffer); // Écriture du fils gauche et du fils droit - _writeVertex(*vertex.child_l, buffer); - _writeVertex(*vertex.child_r, buffer); + writeTree(tree->child_l, buffer); + writeTree(tree->child_r, buffer); } else { - // Séquence de 9 bits encodant la feuille rencontrée - // (0 + octet du caractère) - pushToBuffer(0, buffer); + // Bit "0" indiquant que le sommet n'a pas d'enfants + putBuffer(0, buffer); + // Écriture de la valeur du sommet for (int i = 7; i >= 0; i--) { - pushToBuffer( - // Écriture du n-ième bit du caractère du fils - // dans le tampon - (vertex.name & (1 << i)) != 0, - buffer - ); + putBuffer((tree->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) { - // TODO: implémenter la lecture des arbres - exit(0); +HufTree readTree(ReadBuffer* buffer) { + HufTree tree = malloc(sizeof(*tree)); + + 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) { - _freeTreeVertex(tree.root); - tree.root = NULL; -} - -void _freeTreeVertex(HufVertex* vert) { - if (vert->child_l != NULL && vert->child_r != NULL) { - _freeTreeVertex(vert->child_l); - _freeTreeVertex(vert->child_r); + if (tree->child_l != NULL && tree->child_r != NULL) { + freeTree(tree->child_l); + freeTree(tree->child_r); } - free(vert); + free(tree); } char** createTreeLabels(HufTree input) { @@ -217,7 +189,7 @@ char** createTreeLabels(HufTree input) { labels[i] = NULL; } - _labelVertex(*input.root, labels, NULL, 0); + _labelVertex(*input, labels, NULL, 0); return labels; }