logo

Huffman codant Java

L'algorithme de codage de Huffman a été proposé par David A. Huffman en 1950. C'est un compression de données sans perte mécanisme. Il est également connu sous le nom codage de compression de données. Il est largement utilisé dans la compression d’images (JPEG ou JPG). Dans cette section, nous aborderons les Codage de Huffman et décodage, et également implémenter son algorithme dans un programme Java.

Nous savons que chaque caractère est une séquence de 0 et de 1 et est stocké sur 8 bits. Le mécanisme s'appelle codage de longueur fixe car chaque caractère utilise le même nombre de stockage à bits fixes.

si instruction java

Ici, une question se pose, est-il possible de réduire la quantité d'espace nécessaire pour stocker un personnage ?

Oui, c'est possible en utilisant codage de longueur variable. Dans ce mécanisme, nous exploitons certains caractères qui apparaissent plus fréquemment que d'autres caractères. Dans cette technique de codage, nous pouvons représenter le même morceau de texte ou la même chaîne en réduisant le nombre de bits.

Encodage Huffman

Le codage de Huffman implémente les étapes suivantes.

  • Il attribue un code de longueur variable à tous les caractères donnés.
  • La longueur du code d'un caractère dépend de la fréquence à laquelle il apparaît dans le texte ou la chaîne donnée.
  • Un caractère obtient le plus petit code s'il apparaît fréquemment.
  • Un caractère obtient le code le plus grand s'il apparaît le moins.

Le codage de Huffman suit un règle de préfixe cela évite toute ambiguïté lors du décodage. La règle garantit également que le code attribué au caractère n'est pas traité comme un préfixe du code attribué à un autre caractère.

Le codage de Huffman comporte les deux étapes principales suivantes :

  • Tout d’abord, construisez un Arbre de Huffman à partir de la chaîne d'entrée, des caractères ou du texte donnés.
  • Attribuez un code Huffman à chaque caractère en parcourant l'arborescence.

Brèvez les deux étapes ci-dessus.

Arbre de Huffman

Étape 1: Pour chaque caractère du nœud, créez un nœud feuille. Le nœud feuille d'un caractère contient la fréquence de ce caractère.

Étape 2: Définissez tous les nœuds dans l’ordre trié en fonction de leur fréquence.

télécharger autocad 2019 anglais mediafire

Étape 3: Il peut exister une condition dans laquelle deux nœuds peuvent avoir la même fréquence. Dans un tel cas, procédez comme suit :

  1. Créez un nouveau nœud interne.
  2. La fréquence du nœud sera la somme des fréquences de ces deux nœuds qui ont la même fréquence.
  3. Marquez le premier nœud comme enfant de gauche et un autre nœud comme enfant de droite du nœud interne nouvellement créé.

Étape 4: Répétez les étapes 2 et 3 jusqu'à ce que tous les nœuds forment un seul arbre. Ainsi, nous obtenons un arbre de Huffman.

Exemple de codage Huffman

Supposons que nous devions coder une chaîne Abra Cadabra. Déterminez les éléments suivants :

  1. Code Huffman pour tous les personnages
  2. Longueur moyenne du code pour la chaîne donnée
  3. Longueur de la chaîne codée

(i) Code Huffman pour tous les personnages

Afin de déterminer le code de chaque caractère, nous construisons d’abord un Arbre de Huffman.

Étape 1: Faites des paires de caractères et leurs fréquences.

(une, 5), (b, 2), (c, 1), (d, 1), (r, 2)

Étape 2: Trions les paires par fréquence, on obtient :

(c, 1), (d, 1), (b, 2) (r, 2), (a, 5)

Étape 3: Choisissez les deux premiers caractères et joignez-les sous un nœud parent.

Huffman codant Java

On observe qu'un nœud parent n'a pas de fréquence donc, il faut lui attribuer une fréquence. La fréquence du nœud parent sera la somme de ses nœuds enfants (gauche et droite), c'est-à-dire 1+1= 2.

comment télécharger une vidéo youtube vlc
Huffman codant Java

Étape 4: Répétez les étapes 2 et 3 jusqu'à ce que nous obtenions un seul arbre.

On observe que les paires sont déjà triées (par l'étape 2). Encore une fois, choisissez les deux premières paires et rejoignez-les.

Huffman codant Java

On observe qu'un nœud parent n'a pas de fréquence donc, il faut lui attribuer une fréquence. La fréquence du nœud parent sera la somme de ses nœuds enfants (gauche et droit), c'est-à-dire 2+2= 4.

Huffman codant Java

Encore une fois, nous vérifions si les paires sont triées ou non. A cette étape, nous devons trier les paires.

Huffman codant Java

D'après l'étape 3, choisissez les deux premières paires et joignez-les, nous obtenons :

Huffman codant Java

On observe qu'un nœud parent n'a pas de fréquence donc, il faut lui attribuer une fréquence. La fréquence du nœud parent sera la somme de ses nœuds enfants (gauche et droite), c'est-à-dire 2+4= 6.

Huffman codant Java

Encore une fois, nous vérifions si les paires sont triées ou non. A cette étape, nous devons trier les paires. Après tri, l'arbre ressemble à ceci :

Huffman codant Java

D'après l'étape 3, choisissez les deux premières paires et joignez-les, nous obtenons :

Huffman codant Java

On observe qu'un nœud parent n'a pas de fréquence donc, il faut lui attribuer une fréquence. La fréquence du nœud parent sera la somme de ses nœuds enfants (gauche et droit), c'est-à-dire 5+6= onze.

Huffman codant Java

Nous obtenons donc un seul arbre.

Enfin, nous trouverons le code de chaque caractère à l’aide de l’arborescence ci-dessus. Attribuez un poids à chaque bord. Notez que chacun la pondération du bord gauche est 0 et le La pondération du bord droit est de 1.

Huffman codant Java

Nous observons que les caractères d'entrée ne sont présentés que dans les nœuds de sortie et que les nœuds internes ont des valeurs nulles. Afin de trouver le code de Huffman pour chaque caractère, parcourez l'arbre de Huffman du nœud racine au nœud feuille du caractère particulier pour lequel nous voulons trouver le code. Le tableau décrit le code et la longueur du code pour chaque caractère.

Personnage Fréquence Code Longueur du code
UN 5 0 1
B 2 111 3
C 1 1100 4
D 1 1101 4
R. 2 dix 2

Nous observons que le caractère le plus fréquent obtient la longueur de code la plus courte et que le caractère le moins fréquent obtient la longueur de code la plus grande.

types de données SQL

Maintenant nous pouvons coder la chaîne (Abra Cadabra) que nous avons pris ci-dessus.

 0 111 10 0 1100 0 1101 0 111 10 0 

(ii) Longueur moyenne du code pour la chaîne

La longueur moyenne du code de l'arbre de Huffman peut être déterminée à l'aide de la formule ci-dessous :

 Average Code Length = ∑ ( frequency × code length ) / ∑ ( frequency ) 

= { (5 x 1) + (2 x 3) + (1 x 4) + (1 x 4) + (2 x 2) } / (5+2+1+1+2)

= 2.09090909

(iii) Longueur de la chaîne codée

La longueur du message codé peut être déterminée à l'aide de la formule suivante :

 length= Total number of characters in the text x Average code length per character 

= 11 x 2,09090909

= 23 bits

Algorithme de codage de Huffman

 Huffman (C) n=|C| Q=C for i=1 to n-1 do z=allocate_Node() x=left[z]=Extract_Min(Q) y=right[z]=Extract_Min(Q) f[z]=f[x]+f[y] Insert(Q,z) return Extract_Min(Q) 

L'algorithme de Huffman est un algorithme glouton. Car à chaque étape, l’algorithme recherche les meilleures options disponibles.

La complexité temporelle du codage de Huffman est O (nlogn). Où n est le nombre de caractères dans le texte donné.

Décodage de Huffman

Le décodage de Huffman est une technique qui convertit les données codées en données initiales. Comme nous l'avons vu en codage, l'arbre de Huffman est fait pour une chaîne d'entrée et les caractères sont décodés en fonction de leur position dans l'arbre. Le processus de décodage est le suivant :

téléchargement turbo c++
  • Commencez à parcourir l'arbre à partir du racine nœud et recherchez le personnage.
  • Si on se déplace vers la gauche dans l'arbre binaire, ajoutez 0 au code.
  • Si nous nous déplaçons vers la droite dans l’arbre binaire, ajoutons 1 au code.

Le nœud enfant contient le caractère d'entrée. On lui attribue le code formé par les 0 et les 1 suivants. La complexité temporelle du décodage d'une chaîne est Sur), où n est la longueur de la chaîne.

Programme Java d'encodage et de décodage Huffman

Dans le programme suivant, nous avons utilisé des structures de données telles que des files d'attente prioritaires, des piles et des arbres pour concevoir une logique de compression et de décompression. Nous baserons nos utilitaires sur la technique algorithmique largement utilisée du codage de Huffman.

HuffmanCode.java

 import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.PriorityQueue; //defining a class that creates nodes of the tree class Node { //storing character in ch variable of type character Character ch; //storing frequency in freq variable of type int Integer freq; //initially both child (left and right) are null Node left = null; Node right = null; //creating a constructor of the Node class Node(Character ch, Integer freq) { this.ch = ch; this.freq = freq; } //creating a constructor of the Node class public Node(Character ch, Integer freq, Node left, Node right) { this.ch = ch; this.freq = freq; this.left = left; this.right = right; } } //main class public class HuffmanCode { //function to build Huffman tree public static void createHuffmanTree(String text) { //base case: if user does not provides string if (text == null || text.length() == 0) { return; } //count the frequency of appearance of each character and store it in a map //creating an instance of the Map Map freq = new HashMap(); //loop iterates over the string and converts the text into character array for (char c: text.toCharArray()) { //storing character and their frequency into Map by invoking the put() method freq.put(c, freq.getOrDefault(c, 0) + 1); } //create a priority queue that stores current nodes of the Huffman tree. //here a point to note that the highest priority means the lowest frequency PriorityQueue pq = new PriorityQueue(Comparator.comparingInt(l -&gt; l.freq)); //loop iterate over the Map and returns a Set view of the mappings contained in this Map for (var entry: freq.entrySet()) { //creates a leaf node and add it to the queue pq.add(new Node(entry.getKey(), entry.getValue())); } //while loop runs until there is more than one node in the queue while (pq.size() != 1) { //removing the nodes having the highest priority (the lowest frequency) from the queue Node left = pq.poll(); Node right = pq.poll(); //create a new internal node with these two nodes as children and with a frequency equal to the sum of both nodes&apos; frequencies. Add the new node to the priority queue. //sum up the frequency of the nodes (left and right) that we have deleted int sum = left.freq + right.freq; //adding a new internal node (deleted nodes i.e. right and left) to the queue with a frequency that is equal to the sum of both nodes pq.add(new Node(null, sum, left, right)); } //root stores pointer to the root of Huffman Tree Node root = pq.peek(); //trace over the Huffman tree and store the Huffman codes in a map Map huffmanCode = new HashMap(); encodeData(root, &apos;&apos;, huffmanCode); //print the Huffman codes for the characters System.out.println(&apos;Huffman Codes of the characters are: &apos; + huffmanCode); //prints the initial data System.out.println(&apos;The initial string is: &apos; + text); //creating an instance of the StringBuilder class StringBuilder sb = new StringBuilder(); //loop iterate over the character array for (char c: text.toCharArray()) { //prints encoded string by getting characters sb.append(huffmanCode.get(c)); } System.out.println(&apos;The encoded string is: &apos; + sb); System.out.print(&apos;The decoded string is: &apos;); if (isLeaf(root)) { //special case: For input like a, aa, aaa, etc. while (root.freq-- &gt; 0) { System.out.print(root.ch); } } else { //traverse over the Huffman tree again and this time, decode the encoded string int index = -1; while (index <sb.length() - 1) { index="decodeData(root," index, sb); } traverse the huffman tree and store codes in a map function that encodes data public static void encodedata(node root, string str, huffmancode) if (root="=" null) return; checks node is leaf or not (isleaf(root)) huffmancode.put(root.ch, str.length()> 0 ? str : &apos;1&apos;); } encodeData(root.left, str + &apos;0&apos;, huffmanCode); encodeData(root.right, str + &apos;1&apos;, huffmanCode); } //traverse the Huffman Tree and decode the encoded string function that decodes the encoded data public static int decodeData(Node root, int index, StringBuilder sb) { //checks if the root node is null or not if (root == null) { return index; } //checks if the node is a leaf node or not if (isLeaf(root)) { System.out.print(root.ch); return index; } index++; root = (sb.charAt(index) == &apos;0&apos;) ? root.left : root.right; index = decodeData(root, index, sb); return index; } //function to check if the Huffman Tree contains a single node public static boolean isLeaf(Node root) { //returns true if both conditions return ture return root.left == null &amp;&amp; root.right == null; } //driver code public static void main(String args[]) { String text = &apos;javatpoint&apos;; //function calling createHuffmanTree(text); } } </sb.length()>

Sortir:

 Huffman Codes of the characters are: {p=000, a=110, t=111, v=001, i=010, j=011, n=100, o=101} The initial string is: javatpoint The encoded string is: 011110001110111000101010100111 The decoded string is: javatpoint