#include "arbre.h" void listeVersArbre(Liste *liste) { Cellule *curseur = *liste; while (curseur != NULL) { // parcours de la liste if (curseur->suivant != NULL) { // on créer un mini-arbre qu'on colle au reste de l'arbre seulement si le suivant existe Cellule *nouvelleCellule; if ((nouvelleCellule = (Cellule*)malloc(sizeof(Cellule))) == NULL) { // on alloue de la mémoire pour notre nouvelle cellule (mini-racine) printf("Impossible d'allouer de la mémoire supplémentaire (listeVersArbre).\n"); // gestion de l'erreur exit(1); } nouvelleCellule->gauche = curseur; // membre gauche = curseur nouvelleCellule->droite = curseur->suivant; // membre droit = élément suivant dans la liste nouvelleCellule->lettre = '\0'; nouvelleCellule->frequence = nouvelleCellule->gauche->frequence + nouvelleCellule->droite->frequence; curseur = curseur->suivant->suivant; // on va au suivant 2x car on a déjà ajouté le suivant en tant que membre droit *liste = curseur; // on change le point de départ de notre liste pour ne pas traiter en boucle les anciennes cellules ajouterRangee(liste, nouvelleCellule); // on ajoute à la liste notre nouvelle cellule curseur = *liste; // on met à jour le curseur } else { // cas du dernier élément *liste = curseur; curseur = curseur->suivant; } } } void assignationCode(Arbre arbre, int codeActuel, int longueur, Lettre *lettresListe, int *i, int *longueurTotale) { if (arbre->lettre != '\0') { // si c'est une lettre qu'on regarde lettresListe[*i].lettre = arbre->lettre; // ajout de la lettre lettresListe[*i].code = codeActuel; // assignation de son code lettresListe[*i].longueur = longueur; // longueur du code (ex: 1001 est de taille 4) *i += 1; // on incrémente de 1 *longueurTotale += longueur * arbre->frequence; // incrémente la taille du code à la taille totale finale } else { // si c'est une "mini-racine" longueur++; codeActuel <<= 1; // décalage de bit vers la gauche assignationCode(arbre->gauche, codeActuel, longueur, lettresListe, i, longueurTotale); // appel récursif arbre de gauche codeActuel |= 1; // copie de bit si nécessaire (porte ou) assignationCode(arbre->droite, codeActuel, longueur, lettresListe, i, longueurTotale); // appel récursif arbre de droite } } void freeArbre(Arbre arbre) { if (arbre->lettre == '\0') { // free aussi les mini-racines freeArbre(arbre->gauche); freeArbre(arbre->droite); } free(arbre); // free du noeud courant } Lettre * arbreVersListe(Arbre arbre, int taille, int *tailleTotale) { Lettre *lettres; if ((lettres = (Lettre*)malloc(taille * sizeof(Lettre))) == NULL) { // on alloue la liste qui va contenir nos caractères printf("Impossible d'allouer de la mémoire supplémentaire (arbreVersListe).\n"); // gestion de l'erreur exit(1); } int i = 0; // initialisation de `i` au début car `assignationCode` est récursif assignationCode(arbre, '\0', 0, lettres, &i, tailleTotale); // on commence avec une racine nulle et une taille de 0 freeArbre(arbre); return lettres; } void compression(FILE *entree, FILE *sortie) { /* fclose temporaire pour supprimer les warnings */ fclose(entree); fclose(sortie); } void decompression(FILE *entree, FILE *sortie) { /* fclose temporaire pour supprimer les warnings */ fclose(entree); fclose(sortie); }