package bitio;
import java.io.*;
import java.net.URL;
import java.util.Arrays;
public class AdHuffman
{
private static final int EOC = 256;
public static String[] ascii =
{"NUL","SOH","STX","ETX","EOT","ENQ","ACK","BEL","BS","HT","LF",
"VT","FF","CR","SO","SI","DLE","DC1","DC2","DC3","DC4","NAK",
"SYN","ETB","CAN","EM","SUB","ESC","FS","GS","RS","US"};
private final static class Node
{
private int frekvens;
private int c;
private int nummer;
private Node forelder;
private Node venstre = null;
private Node høyre = null;
private Node(int frekvens, int c, int nummer, Node forelder)
{
this.frekvens = frekvens;
this.c = c;
this.nummer = nummer;
this.forelder = forelder;
}
@Override
public String toString()
{
String s = "(" + nummer + "," + frekvens;
if (c >= 0)
{
if (c < 32) s += "," + ascii[32];
else s += "," + (char)c;
}
return s + ")";
}
}
private Node rot, NULL;
private Node[] noder;
private Node[] tegn;
int antall = 0;
public AdHuffman()
{
rot = NULL = new Node(0, -1, 0, null);
noder = new Node[2 * 8 + 1];
noder[antall++] = rot;
tegn = new Node[257];
}
private static void bytt(Node p, Node q, Node[] noder)
{
Node f = p.forelder, g = q.forelder;
if (p == f.venstre) f.venstre = q;
else f.høyre = q;
if (q == g.høyre) g.høyre = p;
else g.venstre = p;
p.forelder = g;
q.forelder = f;
noder[q.nummer] = p;
noder[p.nummer] = q;
int nummer = p.nummer;
p.nummer = q.nummer;
q.nummer = nummer;
}
private Node nyttTegn(int c)
{
if (antall == noder.length)
{
noder = Arrays.copyOf(noder,2*antall - 1);
}
Node p = NULL;
p.høyre = new Node(1,c,antall,p);
tegn[c] = p.høyre;
noder[antall++] = p.høyre;
p.venstre = new Node(0,-1,antall,p);
noder[antall++] = p.venstre;
NULL = p.venstre;
if (p == rot) return p;
p.frekvens = 1;
return p.forelder;
}
private void oppdater(int c)
{
Node p = tegn[c];
if (p == null) p = nyttTegn(c);
while (p != rot)
{
if (noder[p.nummer - 1].frekvens == p.frekvens)
{
int k = p.nummer - 1;
while (noder[k-1].frekvens == p.frekvens) k--;
Node q = noder[k];
if (q != p.forelder) bytt(p,q,noder);
}
p.frekvens++;
p = p.forelder;
}
}
public static void skrivTre(String melding)
{
AdHuffman h = new AdHuffman();
char[] tegn = melding.toCharArray();
for (char c : tegn) h.oppdater(c);
for (int i = 0; i < h.antall; i++)
System.out.print(h.noder[i] + " ");
}
}