-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathHuffmanCoding.java
More file actions
169 lines (138 loc) · 3.97 KB
/
Copy pathHuffmanCoding.java
File metadata and controls
169 lines (138 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package common;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;
// A Tree node
class Node
{
Character ch;
Integer freq;
Node left = null, right = null;
Node(Character ch, Integer freq)
{
this.ch = ch;
this.freq = freq;
}
public Node(Character ch, Integer freq, Node left, Node right)
{
this.ch = ch;
this.freq = freq;
this.left = left;
this.right = right;
}
}
class Main
{
// Traverse the Huffman Tree and store Huffman Codes in a map.
public static void encode(Node root, String str,
Map<Character, String> huffmanCode)
{
if (root == null) {
return;
}
// Found a leaf node
if (isLeaf(root)) {
huffmanCode.put(root.ch, str.length() > 0 ? str : "1");
}
encode(root.left, str + '0', huffmanCode);
encode(root.right, str + '1', huffmanCode);
}
// Traverse the Huffman Tree and decode the encoded string
public static int decode(Node root, int index, StringBuilder sb)
{
if (root == null) {
return index;
}
// Found a leaf node
if (isLeaf(root))
{
System.out.print(root.ch);
return index;
}
index++;
root = (sb.charAt(index) == '0') ? root.left : root.right;
index = decode(root, index, sb);
return index;
}
// Utility function to check if Huffman Tree contains only a single node
public static boolean isLeaf(Node root) {
return root.left == null && root.right == null;
}
// Builds Huffman Tree and decodes the given input text
public static void buildHuffmanTree(String text)
{
// Base case: empty string
if (text == null || text.length() == 0) {
return;
}
// Count the frequency of appearance of each character
// and store it in a map
Map<Character, Integer> freq = new HashMap<>();
for (char c: text.toCharArray()) {
freq.put(c, freq.getOrDefault(c, 0) + 1);
}
// create a priority queue to store live nodes of the Huffman tree.
// Notice that the highest priority item has the lowest frequency
PriorityQueue<Node> pq;
pq = new PriorityQueue<>(Comparator.comparingInt(l -> l.freq));
// create a leaf node for each character and add it
// to the priority queue.
for (Entry<Character, Integer> entry: freq.entrySet()) {
pq.add(new Node(entry.getKey(), entry.getValue()));
}
// do till there is more than one node in the queue
while (pq.size() != 1)
{
// Remove the two nodes of 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'
// frequencies. Add the new node to the priority queue.
int sum = left.freq + right.freq;
pq.add(new Node(null, sum, left, right));
}
// `root` stores pointer to the root of Huffman Tree
Node root = pq.peek();
// Traverse the Huffman tree and store the Huffman codes in a map
Map<Character, String> huffmanCode = new HashMap<>();
encode(root, "", huffmanCode);
// Print the Huffman codes
System.out.println("Huffman Codes are: " + huffmanCode);
System.out.println("The original string is: " + text);
// Print encoded string
StringBuilder sb = new StringBuilder();
for (char c: text.toCharArray()) {
sb.append(huffmanCode.get(c));
}
System.out.println("The encoded string is : " + sb);
System.out.print("The decoded string is : ");
if (isLeaf(root))
{
// Special case: For input like a, aa, aaa, etc.
while (root.freq-- > 0) {
System.out.print(root.ch);
}
}
else {
// Traverse the Huffman Tree again and this time,
// decode the encoded string
int index = -1;
while (index < sb.length() - 1) {
index = decode(root, index, sb);
}
}
}
// Huffman coding algorithm implementation in Java
public static void main(String[] args)
{
// Ax = { A, B, C, D, E }
// Px = { 0.25, 0.125, 0.0625, 0.0625, 0.5 }
// total 18,
String text = "AAAABBCDEEEEEEEE";
buildHuffmanTree(text);
}
}