Aïe... Va falloir que tu fasses des efforts sur l'indentation, c'est absolument horrible, là... Ca commence dès la première ligne, par les espaces après les "#" (#include, #define)... Va falloir retravailler ça, c'est franchement pas génial à lire. En plus, t'es avare de commentaires, c'est encore plus difficile à lire.
Pour ton problème de récursivité, c'est que tu n'as pas dû correctement arrêter ton algorithme, car c'est bien en général une fonction récursive que l'on utilise pour cette opération.
Ensuite, je suis assez étonné de te voir arrêter arbitrairement la taille de tes codes de Huffman à 8 bits (#define M) : qui t'as dit que c'était le cas ? Ces codes peuvent aller jusqu'à 64 bits, si je me rappelle bien le pire cas possible !
Ensuite, les erreurs que j'ai pu relever :
1) Pas d'assertions ni de tests sur le dépassement du champ "code" de ta structure... Rajoute un "assert( i<8 );" dans le code avant chaque assignation à "tmp->code[i]". Ton débordement peut venir de là.
2) Tu fais un "malloc" sur tmp sans tester le retour. En plus, tu ne libère jamais cette mémoire !! Surtout que tu n'as pas besoin d'un malloc, tu peux utiliser une déclaration "CODE c ;" et utiliser "&c" (adresse de c) si tu veux un pointeur dessus... Pointeur dont tu n'as pas besoin ici, en plus. Bref, là, c'est la grosse zone.
3) Ton parcours d'arbre gauche et droit n'est pas séparé : une fois effectué celui sur le fils gauche, tu vas faire celui sur le fils droit... Et les codes vont se mélanger, car la variable "c" est globale et non pas locale à ta procédure => on ne peut pas utiliser la récursivité "comme ça" dans ces conditions.
Bref, c'est plutôt étrange que ton code arrive à fonctionner, même un peu... Corriges-ça de toute urgence, ça en a vraiment besoin.
J'utilisais une déclaration de ce type pour les noeuds de l'arbre :Envoyé par ben13Si la fréquence est non-nulle,c 'est une feuille, car les caractères n'apparaissant jamais dans le fichier d'origine n'apparaissent pas non plus dans la structure d'arbre. Si ce n'est pas une feuille, la valeur du caractère n'est même pas examinée (elle devait être à zéro, je pense).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 typedef struct _Node { unsigned char C ; // Valeur du caractère ASCII du noeud unsigned long int F ; // Fréquence du caractère, permet aussi de tester si le noeud est une feuille. unsigned long int CF ; // Cumul des fréquences des deux sous-arbres. struct _Node* Left ; // Sous-arbre gauche. struct _Node* Right ; // Sous-arbre droit. } TNode ;
Le cumul des fréquences sert pour l'insertion correcte d'une cellule dans l'arbre. On peut faire sans, mais ça simplifie le code résultant.
Le code de Huffman n'est bien entendu pas stocké, car il est équivalent au parcours de l'arbre (0=Left, 1=Right). Chaque noeud de l'arbre peut être une feuille aussi, avec ou sans sous-arbres.
Pour la phase de compression, j'utilisais une LUT : un tableau contenant tous les codes de Huffman, avec leur longueur (importante dans ce cas). Ainsi, je ne parcourais l'arbre qu'une seule fois.
Partager