init
This commit is contained in:
117
p3/HuffmanCode.java
Normal file
117
p3/HuffmanCode.java
Normal file
@@ -0,0 +1,117 @@
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class HuffmanCode {
|
||||
|
||||
public HuffmanNode root;
|
||||
|
||||
// Constructor that builds the Huffman tree from an array of frequencies
|
||||
public HuffmanCode(int[] frequencies) {
|
||||
Queue<HuffmanNode> nodes = new PriorityQueue<>();
|
||||
for (int i = 0; i < frequencies.length; i++) {
|
||||
if (frequencies[i] > 0) {
|
||||
nodes.add(new HuffmanNode((char) i, frequencies[i]));
|
||||
}
|
||||
}
|
||||
while (nodes.size() > 1) {
|
||||
HuffmanNode left = nodes.remove();
|
||||
HuffmanNode right = nodes.remove();
|
||||
HuffmanNode branch = new HuffmanNode('\0', left.freq + right.freq, left, right);
|
||||
nodes.add(branch);
|
||||
}
|
||||
this.root = nodes.isEmpty() ? null : nodes.remove();
|
||||
}
|
||||
|
||||
// Constructor that reads the Huffman tree from a Scanner
|
||||
public HuffmanCode(Scanner input) {
|
||||
this.root = new HuffmanNode('\0', 0); // Initialize root with a dummy node
|
||||
while (input.hasNextLine()) {
|
||||
int character = Integer.parseInt(input.nextLine());
|
||||
String path = input.nextLine();
|
||||
addNode(character, path);
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a node to the Huffman tree based on the given path
|
||||
private void addNode(int character, String path) {
|
||||
HuffmanNode current = root;
|
||||
for (int i = 0; i < path.length(); i++) {
|
||||
char direction = path.charAt(i);
|
||||
if (direction == '0') {
|
||||
if (current.left == null) {
|
||||
if (i == path.length() - 1) {
|
||||
current.left = new HuffmanNode((char) character, 1); // Final node
|
||||
} else {
|
||||
current.left = new HuffmanNode('\0', 0); // Create a dummy node if it doesn't exist
|
||||
}
|
||||
}
|
||||
current = current.left;
|
||||
} else if (direction == '1') {
|
||||
if (current.right == null) {
|
||||
if (i == path.length() - 1) {
|
||||
current.right = new HuffmanNode((char) character, 1); // Final node
|
||||
} else {
|
||||
current.right = new HuffmanNode('\0', 0); // Create a dummy node if it doesn't exist
|
||||
}
|
||||
}
|
||||
current = current.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Saves the Huffman tree to the given output stream in standard format
|
||||
public void save(PrintStream output) {
|
||||
save(output, this.root, "");
|
||||
}
|
||||
|
||||
private void save(PrintStream output, HuffmanNode head, String path) {
|
||||
if (head != null) {
|
||||
if (head.data != '\0') {
|
||||
output.println((int) head.data);
|
||||
output.println(path);
|
||||
}
|
||||
save(output, head.left, path + "0");
|
||||
save(output, head.right, path + "1");
|
||||
}
|
||||
}
|
||||
|
||||
// Translates bits from the input stream to characters and writes them to the output stream
|
||||
public void translate(BitInputStream input, PrintStream output) {
|
||||
HuffmanNode current = root;
|
||||
while (input.hasNextBit()) {
|
||||
int bit = input.nextBit();
|
||||
if (bit == 0) {
|
||||
current = current.left;
|
||||
} else {
|
||||
current = current.right;
|
||||
}
|
||||
if (current.left == null && current.right == null) { // Leaf node
|
||||
output.print(current.data);
|
||||
current = root; // Restart for next character
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inner class representing a node in the Huffman tree
|
||||
private static class HuffmanNode implements Comparable<HuffmanNode> {
|
||||
public char data;
|
||||
public int freq;
|
||||
public HuffmanNode left;
|
||||
public HuffmanNode right;
|
||||
|
||||
public HuffmanNode(char data, int frequency) {
|
||||
this(data, frequency, null, null);
|
||||
}
|
||||
|
||||
public HuffmanNode(char data, int frequency, HuffmanNode left, HuffmanNode right) {
|
||||
this.data = data;
|
||||
this.freq = frequency;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public int compareTo(HuffmanNode other) {
|
||||
return Integer.compare(this.freq, other.freq);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user