20182305 Huffman编码实践的设计和实现过程
实践内容
设有字符集:S={a,b,c,d,e,f,g,h,i,j,k,l,m,n.o.p.q,r,s,t,u,v,w,x,y,z}。
给定一个包含26个英文字母的文件,统计每个字符出现的概率,根据计算的概率构造一颗哈夫曼树。
并完成对英文文件的编码和解码。
要求:
(1)准备一个包含26个英文字母的英文文件(可以不包含标点符号等),统计各个字符的概率
(2)构造哈夫曼树
(3)对英文文件进行编码,输出一个编码后的文件
(4)对编码文件进行解码,输出一个解码后的文件
什么是哈夫曼树
给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
设计过程
File file = new File("E:\\JAVA\\111\\WindowsCode\\src\\Week10\\Huffman\\text1.txt");
Readtxt read = new Readtxt();
String temp = read.txtString(file);
int[] num = read.getNumber();
char[] chars = read.getChars();
for(int i = 0;i<26;i++){
System.out.print(chars[i]+":"+num[i]+" ");
list.add(new Node<String>(chars[i]+"",num[i]));
}
Collections.sort(list);
System.out.println();
HuffmanTree hufftree = new HuffmanTree();
Node<String> root = hufftree.createTree(list);
for(int i = 0;i<list2.size();i++)
{
if(list2.get(i).getData()!=null)
{
list3.add(list2.get(i).getData());
list4.add(list2.get(i).getCode());
}
}
for(int i = 0;i<list2.size();i++)
{
num2 += list2.get(i).getWeight();
}
for(int i = 1;i<list3.size();i++)
{
System.out.println(list3.get(i) + "出现的概率为" + list2.get(i).getWeight()/num2 + " ");
}
System.out.println();
public Node<T> createTree(List<Node<T>> nodes)
{
while (nodes.size() > 1)
{
Collections.sort(nodes);
Node<T> left = nodes.get(nodes.size() - 2);
left.setCode(0 + "");
Node<T> right = nodes.get(nodes.size() - 1);
right.setCode(1 + "");
Node<T> parent = new Node<T>(null, left.getWeight() + right.getWeight());
parent.setLeft(left);
parent.setRight(right);
nodes.remove(left);
nodes.remove(right);
nodes.add(parent);
}
return nodes.get(0);
}
char[] chars = new char[]{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' '};
int[] number = new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
public String txtString(File file){
StringBuilder result = new StringBuilder();
try{
BufferedReader br = new BufferedReader(new FileReader(file));
String s = null;
//一次读一行
while((s = br.readLine())!=null){
result.append(System.lineSeparator()+s);
num(s);
}
br.close();
}catch(Exception e){
e.printStackTrace();
}
return result.toString();
}
public void num(String string){
for(int i = 0;i<27;i++){
int temp = 0;
for(int j = 0;j<string.length();j++){
if(string.charAt(j) == chars[i])
temp++;
}
number[i] += temp;
}
}
最终结果