利用huffman编码对文本文件进行压缩与解压(java实现)

利用huffman编码对文本文件进行压缩与解压

输入:一个文本文件
输出:压缩后的文件

算法过程:
(1)统计文本文件中每个字符的使用频度
(2)构造huffman编码
(3)以二进制流形式压缩文件

采用哈夫曼编码进行文件的压缩和解压,主要原理是通过huffman编码来表示字符,出现次数多的编码短,出现次数少的编码长,这样整体而言,所需的总的比特位是最少的。但是当大部分字符出现的频率都差不多时,huffman压缩的压缩率就会很低。先统计出文件中各个字符出现的次数;构建哈夫曼树,生成每个字符对应的编码,然后将编码写入压缩文件中;解压缩是将压缩后的文件翻译过来,根据哈夫曼编码找到对应的字符。

package compress_file;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.*;

class HaffmanTree {
   //哈夫曼树类
	public static final int MAXVALUE = 1000;// 最大权值
	public int nodeNum; // 叶子结点个数

	public HaffmanTree(int n) {
   
		this.nodeNum = n;
	}

	public void haffman(char[] names, int[] weight, HaffNode[] nodes) {
   //构造哈夫曼树,weight 权值,nodes 叶子节点
		int n = this.nodeNum;
		int m1, m2, x1, x2;// m1,m2,表示最小的两个权值,x1、x2表示最小两个权值对应的编号,m1表示最小,m2表示次小
		for (int i = 0; i < 2 * n - 1; i++) {
   // 初始化所有的结点,对应有n个叶子结点的哈夫曼树,有2n-1个结点
			HaffNode temp = new HaffNode();
			// 初始化n个叶子结点,就是输入的节点。0、1、2、3是叶子节点也是输入的节点
			if (i < n) {
   
				temp.name = names[i];
				temp.weight = weight[i];
			} else {
   
				temp.name = ' ';
				temp.weight = 0;
			}
			temp.parent = 0;
			temp.flag = 0;
			temp.leftChild = -1;
			temp.rightChild = -1;
			nodes[i] = temp;
		}
		
		for (int i = 0; i < n - 1; i++) {
   // 初始化n-1个非叶子结点,n-1表示要循环n-1次求的n-1个数
			m1 = m2 = MAXVALUE;
			x1 = x2 = 0;
			// 求得这n-1个数时,每次都是从0到n+i-1,并且flag=0的,flag=1表示已经加入到二叉树。
			// 以下是找出权值最小的2个
			for (int j = 0; j < n + i; j++) {
   
				if (nodes[j].weight < m1 && nodes[j].flag == 0) {
   
					// m1,x1初始值为第一个元素,后面如果比m1要小,则m1指向更小的,原来m1指向的现在由m2指向,
					// 如果后面比m1大比m2小,则m2指向这个比m1大比m2小的,
					// 也就是说m1指向最小的,m2指向第2小的。
					m2 = m1;
					x2 = x1;
					m1 = nodes[j].weight;
					x1 = j;
				} else if (nodes[j].weight < m2 && nodes[j].flag == 0) {
   
					m2 = nodes[j].weight;
					x2 = j;
				}
			}
			// 将权值最小的2个组合成一个二叉树
			nodes[x1].parent = n + i;
			nodes[x2].parent = n + i;
			nodes[x1].flag = 1;
			nodes[x2].flag = 1;
			nodes[n + i].weight = nodes[x1].weight + nodes[
  • 8
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值