哈夫曼编码和解码

本文详细介绍了如何实现哈夫曼编码和解码。首先,通过统计字符串中每个字符的频率构建哈夫曼树,得到字符的哈夫曼编码。接着,解释了解码过程,从哈夫曼编码表出发,按编码对应字符还原原始字符串。文章还提供了具体的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在前一文中,介绍了根据权值进行哈夫曼树的构建(https://blog.youkuaiyun.com/m0_51384638/article/details/116278540)。本文,将对传入的字符串进行编码,得出一个哈夫曼编码表,并根据编码表解码,得到原来的数据。
要实现对字符串进行哈夫曼编码和解码,我认为需要解决的问题如下:
1如何统计频率.每一个字符如何与它的权值建立一一对应的关系。
2.搭建哈夫曼树之后,如何得到每一个字符的哈夫曼编码。
3.根据哈夫曼编码表,如何解码得到原来的字符串。

现在,问题依次来解决
1.将字符串转为字节数组,遍历字节数组,将每个字节出现的频率保存到一个新建的数组中,这个必须得保证两个数组的长度一致。比如说在字节数组中,第一个位置的字节的频率必须对应在第二个数组中的第一个位置。但是我不是特别推荐这种方法,在学过的数据结构中,map就是一个键和值一一对应的关系(不考虑有冲突),使用map存储,在后续的编码和解码可以方便很多。
2.依照左0右1的规则,给哈夫曼中的所有路径进行编码,最终的哈夫曼编码即为从根节点到叶子节点路径的编码拼接得到的字符串。使用上文最后得到的哈夫曼树
在这里插入图片描
3节点对应的哈夫曼编码即为:11000,越靠近根节点的哈夫曼编码越短。
3.从哈夫曼编码得到的字符串的第一位开始,一一与编码表对应,如果出现对应的编码即解码成功。例如:编码表为:{97=10, 98=111, 99=0, 107=110},编码字符串为:1010101111110000110,到了第二位数字就在编码表中找到10对应为97,下一步就是从第三位开始,按照上面的规则进行解码。

代码实现
一、编码
使用到的节点类

class Node3 implements Comparable<Node3> {
   
	Byte data;//数据域
	Node3 left,right;
	int weight;//权值域
	public Node3(byte data,int weight) {
   
		this.data = data;
		this.weight = weight;
	}
	public Node3(int weight) {
   
		this.weight = weight;
	}
	public int compareTo(Node3 o) {
   
		// TODO Auto-generated method stub
		return this.weight-o.weight;
	}
	@Override
	public String toString() {
   
		return "Node3 [data=" + data + ", weight=" + weight + "]";
	}
	//前序遍历
	public void preOrder() {
   
		System.out.println(this);
		if(this.left != null)
			this.left.preOrder();
		if(this.right != null)
			this.right.preOrder();
	}	
}

先统计字符串中每个字符出现的频率,并建立映射关系

/**
	 * 
	 * @param str 需要统计的字符串
	 * @return  保存了节点的队列
	 */
public static ArrayList<Node3> creatNode(String str) {
   
		byte[] data = str.getBytes();
		//array用于保存后续建立起来的节点
		ArrayList<Node3> array = new ArrayList
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值