Files
SAE32_2025/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java
T
2026-01-07 19:27:03 +01:00

115 lines
3.2 KiB
Java

package fr.iutfbleau.sae.mhuffman;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
/**
*
* Cette classe construit un arbre de Huffman à partir d'un tableau
* de fréquences. Une fois l'arbre construit, elle permet aussi de
* générer les codes Huffman associés à chaque symbole.
*
* Le principe est le suivant :
* - chaque symbole non nul devient une feuille avec sa fréquence
* - on fusionne toujours les deux plus petites fréquences
* - on obtient une racine unique
* - un parcours de l'arbre permet ensuite de fabriquer les codes
*
* Les codes sont construits en descendant l'arbre :
* aller à gauche ajoute "0", aller à droite ajoute "1".
*/
public class HuffmanTree {
private HuffmanNode root;
private Map<Integer, String> codes;
/**
* Construit l'arbre de Huffman à partir d'un tableau de fréquences.
*
* @param freq tableau contenant la fréquence de chaque symbole (0 à 255)
*/
public HuffmanTree(int[] freq) {
this.root = null;
// Création de la file de priorité avec le comparateur
ComparateurHuffmanNode cmp = new ComparateurHuffmanNode();
PriorityQueue<HuffmanNode> feuilles = new PriorityQueue<>(cmp);
// Ajout des feuilles
for (int i = 0; i < freq.length; i++) {
if (freq[i] > 0) {
feuilles.add(new HuffmanNode(i, freq[i]));
}
}
// Fusion des nœuds (feuille) jusqu'à obtenir la racine
while (feuilles.size() > 1) {
HuffmanNode left = feuilles.poll();
HuffmanNode right = feuilles.poll();
HuffmanNode parent = new HuffmanNode(left, right);
feuilles.add(parent);
}
this.root = feuilles.poll();
}
/**
* Lance la génération des codes Huffman en parcourant l'arbre.
*
* @return une map associant chaque symbole à son code Huffman
*/
public Map<Integer, String> generateCodes() {
this.codes = new HashMap<>();
generateCodesRec(this.root, "");
return this.codes;
}
/**
* Méthode récursive qui construit les codes Huffman.
*
* @param node nœud courant
* @param prefixe code accumulé (suite de 0 et de 1)
*/
private void generateCodesRec(HuffmanNode node, String prefixe) {
// Cas feuille : on ajoute le code
if (node.isLeaf()) {
if (prefixe.length() > 0) {
this.codes.put(node.getValue(), prefixe);
} else {
// Cas spécial : un seul symbole dans l'arbre
this.codes.put(node.getValue(), "0");
}
return;
}
// Descendre à gauche s
generateCodesRec(node.getLeft(), prefixe + "0");
// Descendre à droite
generateCodesRec(node.getRight(), prefixe + "1");
}
/**
* Permet de récupérer la racine de l'arbre.
*
* @return la racine de l'arbre de Huffman
*/
public HuffmanNode getRoot() {
return this.root;
}
/**
* Retourne les codes Huffman générés.
*
* @return une map symbole code
*/
public Map<Integer, String> getCodes() {
return this.codes;
}
}