Section one
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.lang.*;
// 每个字符的信息
class Entry
{
public char symb; //要编码的字符
public int weight; //权重
public String rep; //这个字符得到的编码表示
}
//--------------------------------------------------------------------------------
// Huffman编码频率表
class Table
{
public static int p; // 指示当前读入数据的指针
public final int MAXT = 300; // 最大的字符种类数
public int currTableSize; // 当前表的大小
public Entry[] tab; // 没有分配空间的表
private Reader in; // 存储输入的文件名称
String file = ""; // 用字符串存储文件
private boolean fileOpen = false; // 判断文件是否打开
private String fileName; // 当前文件名称
private int totalChars = 0; // 所读字符总数
char markerChar = '@'; // 终止输入符
//构造方法,输入参数为文件名称或者为空
public Table(String f)
{
fileName = f; //文件名称
currTableSize = 0; //表的大小
tab = new Entry[MAXT]; //为表分配空间
p = 0;
}
//从文件读取字符
public char getNextchar(String s)
{
int i;
char temp_ch;
char[] temp;
temp = new char[s.length()];
temp = s.toCharArray(); //保存从textfield获得的文本数据
temp_ch = temp[p];
p++;
return temp_ch;
}
//的到每个字符并且为其建立表
public void buildTable(String s)
{
char ch = getNextchar(s);
while (ch != 65535 && ch != markerChar) //如果不为@则继续输入
{
totalChars++; //字符数加1
file += ch; //把字符加到尾端
int i = lookUp(ch);
if (i == -1) //如果没有找到这个字符,说明这是一个新的字符种类
{ //新的字符种类
tab[currTableSize] = new Entry(); //为字符开辟新的表空间
tab[currTableSize].symb = ch; //字符
tab[currTableSize].weight = 1; //权重为1
tab[currTableSize].rep = ""; //编码方式为空
currTableSize++; //把当前表的大小加1
}
else //找到这个字符,把权重加1,表中存在这个字符
{
tab[i].weight += 1;
}
ch = getNextchar(s);//继续输入
}
}
//在表中查找这个字符
public int lookUp(char ch)
{
for (int j = 0; j < currTableSize; j++)
{
if (tab[j].symb == ch) //找到相同的字符,返回在表中的编号
{
return j;
}
}
return -1; //否则返回-1
}
}
//--------------------------------------------------------------------------------
//Huffman树结点类,用于编码和解码
class TreeNode
{
public double weight;
public char symb;
public String rep;
public TreeNode left, right; //子女结点
public int step; //需要的步数
}
//--------------------------------------------------------------------------------
//过渡变量,只是多了一个指针
class ListNode
{
public TreeNode hufftree;//Huffman结点类对象
public ListNode next; //指针,指向下一个链表
}
//--------------------------------------------------------------------------------
//创建优先级队列
class PQueue
{
ListNode list = null; // 列表为空
// 插入新的项目到列表中
public void insert(TreeNode t)
{
ListNode l = new ListNode(); //开辟空间
l.hufftree = t; //
l.next = list;
list = l; //list指向最后一个结点
}
//创建初始队列
public void buildList(Entry[] tab, int n)
{
int i;
TreeNode tNode;
for (i = 0; i < n; i++) //把表中的信息一个一个的放入队列中
{
tNode = new TreeNode();
tNode.weight = tab[i].weight;
tNode.left = tNode.right = null;
tNode.symb = tab[i].symb;
tNode.rep = "";
insert(tNode);
}
}
//返回根结点权重最小的(对整个队列进行排序)按权重排序
public TreeNode least()
{
ListNode l, oldl, minl = null, oldminl = null; // = null: for compiler
double minw = 1000000;
oldl = list;
l = list;
while (l != null) //当队列不为空的时候
{
if (l.hufftree.weight < minw)
{
minw = l.hufftree.weight; //得到最小的权重
oldminl = oldl; //指向当前结点
minl = l; //指向最小的
}
oldl = l; //指向当前结点
l = l.next; //指向下一个结点
}
if (minl == oldminl) //返回权重最小的结点
{
list = list.next;
return minl.hufftree;
}
oldminl.next = minl.next;
return minl.hufftree;
}
}