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 <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 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 | ||||
|  |  | |||
							
								
								
									
										102
									
								
								src/huftree.c
								
								
								
								
							
							
						
						
									
										102
									
								
								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--) { | ||||
|             putBuffer((tree->name & (1 << i)) != 0, buffer); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 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--) { | ||||
|             pushToBuffer( | ||||
|                 // Écriture du n-ième bit du caractère du fils
 | ||||
|                 // dans le tampon
 | ||||
|                 (vertex.name & (1 << i)) != 0, | ||||
|                 buffer | ||||
|             ); | ||||
|             name |= getBuffer(buffer) << i; | ||||
|         } | ||||
| 
 | ||||
|         // Séquence de 9 bits indiquant un sommet
 | ||||
|         // sans fils (100000001)
 | ||||
|         pushToBuffer(1, buffer); | ||||
| 
 | ||||
|         for (int i = 0; i < 7; i++) { | ||||
|             pushToBuffer(0, buffer); | ||||
|         tree->name = name; | ||||
|         tree->child_l = NULL; | ||||
|         tree->child_r = NULL; | ||||
|     } | ||||
| 
 | ||||
|         pushToBuffer(1, buffer); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| HufTree readTree(FILE* output) { | ||||
|     // TODO: implémenter la lecture des arbres
 | ||||
|     exit(0); | ||||
|     return tree; | ||||
| } | ||||
| 
 | ||||
| void freeTree(HufTree tree) { | ||||
|     _freeTreeVertex(tree.root); | ||||
|     tree.root = NULL; | ||||
|     if (tree->child_l != NULL && tree->child_r != 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) { | ||||
|  | @ -217,7 +189,7 @@ char** createTreeLabels(HufTree input) { | |||
|         labels[i] = NULL; | ||||
|     } | ||||
| 
 | ||||
|     _labelVertex(*input.root, labels, NULL, 0); | ||||
|     _labelVertex(*input, labels, NULL, 0); | ||||
|     return labels; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue