diff options
Diffstat (limited to 'p3/HuffmanCode.java')
| -rw-r--r-- | p3/HuffmanCode.java | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/p3/HuffmanCode.java b/p3/HuffmanCode.java new file mode 100644 index 0000000..8691ce8 --- /dev/null +++ b/p3/HuffmanCode.java @@ -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); + } + } +} |
