名聚优品 一家只做正品的网站,wordpress视频防止下载文件,个人简历word文档,建设公司门户网站前言
哈夫曼编码是一种经典的无损数据压缩算法#xff0c;它通过赋予出现频率较高的字符较短的编码#xff0c;出现频率较低的字符较长的编码#xff0c;从而实现压缩效果。这篇博客将详细讲解如何使用Java实现哈夫曼编码#xff0c;包括哈夫曼编码的原理、具体实现步骤以…前言
哈夫曼编码是一种经典的无损数据压缩算法它通过赋予出现频率较高的字符较短的编码出现频率较低的字符较长的编码从而实现压缩效果。这篇博客将详细讲解如何使用Java实现哈夫曼编码包括哈夫曼编码的原理、具体实现步骤以及完整的代码示例。
哈夫曼编码原理
哈夫曼编码的基本原理可以概括为以下几个步骤
统计字符频率遍历输入数据统计每个字符出现的频率。构建哈夫曼树根据字符的频率构建一棵哈夫曼树。树的每个节点代表一个字符及其频率树的叶子节点代表具体的字符。生成哈夫曼编码通过遍历哈夫曼树生成每个字符的哈夫曼编码。左子树表示’0’右子树表示’1’。编码数据将原始数据根据哈夫曼编码表转换为二进制数据。解码数据根据哈夫曼树将二进制数据还原为原始字符。
实现步骤
1. 定义哈夫曼树的节点类
首先定义一个内部类Node用于表示哈夫曼树的节点。每个节点包含字符、频率、左子节点和右子节点。实现ComparableNode接口用于在优先队列中排序。
private static class Node implements ComparableNode {private final char ch; // 字符private final int freq; // 频率private final Node left, right; // 左右子节点Node(char ch, int freq, Node left, Node right) {this.ch ch;this.freq freq;this.left left;this.right right;}// 判断是否为叶子节点private boolean isLeaf() {assert ((left null) (right null)) || ((left ! null) (right ! null));return (left null) (right null);}// 根据频率比较节点用于优先队列public int compareTo(Node that) {return this.freq - that.freq;}
}2. 构建哈夫曼树
根据字符频率构建哈夫曼树。我们使用优先队列来实现该步骤。
private static Node buildTrie(int[] freq) {// 初始化优先队列并将每个字符及其频率作为单节点树插入队列MinPQNode pq new MinPQNode();for (char c 0; c R; c)if (freq[c] 0)pq.insert(new Node(c, freq[c], null, null));// 不断合并频率最小的两棵树直到剩下一棵树while (pq.size() 1) {Node left pq.delMin();Node right pq.delMin();Node parent new Node(\0, left.freq right.freq, left, right);pq.insert(parent);}return pq.delMin();
}3. 生成哈夫曼编码表
通过遍历哈夫曼树生成每个字符的哈夫曼编码。
private static void buildCode(String[] st, Node x, String s) {if (!x.isLeaf()) {// 递归遍历左子树路径加0buildCode(st, x.left, s 0);// 递归遍历右子树路径加1buildCode(st, x.right, s 1);} else {// 叶子节点记录字符的编码st[x.ch] s;}
}4. 压缩数据
读取输入数据生成哈夫曼编码表输出编码后的二进制数据。
public static void compress() {// 读取输入字符串并转换为字符数组String s BinaryStdIn.readString();char[] input s.toCharArray();// 计算每个字符的频率int[] freq new int[R];for (int i 0; i input.length; i)freq[input[i]];// 构建哈夫曼树Node root buildTrie(freq);// 建立字符编码表String[] st new String[R];buildCode(st, root, );// 输出哈夫曼树以便解码使用writeTrie(root);// 输出原始未压缩的字节数BinaryStdOut.write(input.length);// 使用哈夫曼编码压缩输入for (int i 0; i input.length; i) {String code st[input[i]];for (int j 0; j code.length(); j) {if (code.charAt(j) 0) {BinaryStdOut.write(false);} else if (code.charAt(j) 1) {BinaryStdOut.write(true);} else throw new IllegalStateException(Illegal state);}}// 关闭输出流BinaryStdOut.close();
}5. 解码数据
读取哈夫曼树和编码后的二进制数据解码还原原始数据。
public static void expand() {// 从输入流中读取哈夫曼树Node root readTrie();// 读取原始字节数int length BinaryStdIn.readInt();// 使用哈夫曼树解码输入的二进制数据并输出字符for (int i 0; i length; i) {Node x root;while (!x.isLeaf()) {boolean bit BinaryStdIn.readBoolean();if (bit) x x.right;else x x.left;}BinaryStdOut.write(x.ch, 8);}BinaryStdOut.close();
}完整代码
以下是完整的哈夫曼编码实现代码
public class Huffman {// 定义扩展ASCII字符集的大小private static final int R 256;// 防止实例化private Huffman() { }// 哈夫曼树的节点类实现了Comparable接口以便于优先队列排序private static class Node implements ComparableNode {private final char ch; // 字符private final int freq; // 频率private final Node left, right; // 左右子节点Node(char ch, int freq, Node left, Node right) {this.ch ch;this.freq freq;this.left left;this.right right;}// 判断是否为叶子节点private boolean isLeaf() {assert ((left null) (right null)) || ((left ! null) (right ! null));return (left null) (right null);}// 根据频率比较节点用于优先队列public int compareTo(Node that) {return this.freq - that.freq;}}// 压缩方法public static void compress() {// 读取输入字符串并转换为字符数组String s BinaryStdIn.readString();char[] input s.toCharArray();// 计算每个字符的频率int[] freq new int[R];for (int i 0; i input.length; i)freq[input[i]];// 构建哈夫曼树Node root buildTrie(freq);// 建立字符编码表String[] st new String[R];buildCode(st, root, );// 输出哈夫曼树以便解码使用writeTrie(root);// 输出原始未压缩的字节数BinaryStdOut.write(input.length);// 使用哈夫曼编码压缩输入for (int i 0; i input.length; i) {String code st[input[i]];for (int j 0; j code.length(); j) {if (code.charAt(j) 0) {BinaryStdOut.write(false);} else if (code.charAt(j) 1) {BinaryStdOut.write(true);} else throw new IllegalStateException(Illegal state);}}// 关闭输出流BinaryStdOut.close();}// 构建哈夫曼树private static Node buildTrie(int[] freq) {// 初始化优先队列并将每个字符及其频率作为单节点树插入队列MinPQNode pq new MinPQNode();for (char c 0; c R; c)if (freq[c] 0)pq.insert(new Node(c, freq[c], null, null));// 不断合并频率最小的两棵树直到剩下一棵树while (pq.size() 1) {Node left pq.delMin();Node right pq.delMin();Node parent new Node(\0, left.freq right.freq, left, right);pq.insert(parent);}return pq.delMin();}// 输出哈夫曼树用于解码private static void writeTrie(Node x) {if (x.isLeaf()) {BinaryStdOut.write(true);BinaryStdOut.write(x.ch, 8);return;}BinaryStdOut.write(false);writeTrie(x.left);writeTrie(x.right);}// 生成哈夫曼编码表private static void buildCode(String[] st, Node x, String s) {if (!x.isLeaf()) {// 递归遍历左子树路径加0buildCode(st, x.left, s 0);// 递归遍历右子树路径加1buildCode(st, x.right, s 1);} else {// 叶子节点记录字符的编码st[x.ch] s;}}// 解码方法public static void expand() {// 从输入流中读取哈夫曼树Node root readTrie();// 读取原始字节数int length BinaryStdIn.readInt();// 使用哈夫曼树解码输入的二进制数据并输出字符for (int i 0; i length; i) {Node x root;while (!x.isLeaf()) {boolean bit BinaryStdIn.readBoolean();if (bit) x x.right;else x x.left;}BinaryStdOut.write(x.ch, 8);}BinaryStdOut.close();}// 从输入流中读取哈夫曼树private static Node readTrie() {boolean isLeaf BinaryStdIn.readBoolean();if (isLeaf) {return new Node(BinaryStdIn.readChar(), -1, null, null);} else {return new Node(\0, -1, readTrie(), readTrie());}}// 主方法根据参数决定执行压缩或解码public static void main(String[] args) {if (args[0].equals(-)) compress();else if (args[0].equals()) expand();else throw new IllegalArgumentException(Illegal command line argument);}
}总结
哈夫曼编码是一种高效的无损数据压缩算法。本文通过详细的代码示例展示了如何使用Java实现哈夫曼编码的压缩和解压功能。从统计字符频率、构建哈夫曼树、生成哈夫曼编码表到最终的编码和解码涵盖了哈夫曼编码的全部核心步骤。希望这篇博客能够帮助你更好地理解哈夫曼编码的实现原理和具体的编码实践。 文章转载自: http://www.morning.rsnn.cn.gov.cn.rsnn.cn http://www.morning.rnhh.cn.gov.cn.rnhh.cn http://www.morning.rgnp.cn.gov.cn.rgnp.cn http://www.morning.lzzqz.cn.gov.cn.lzzqz.cn http://www.morning.bpmz.cn.gov.cn.bpmz.cn http://www.morning.mslsn.cn.gov.cn.mslsn.cn http://www.morning.bncrx.cn.gov.cn.bncrx.cn http://www.morning.mflqd.cn.gov.cn.mflqd.cn http://www.morning.qmncj.cn.gov.cn.qmncj.cn http://www.morning.kyzja.com.gov.cn.kyzja.com http://www.morning.yhsrp.cn.gov.cn.yhsrp.cn http://www.morning.zxwqt.cn.gov.cn.zxwqt.cn http://www.morning.wqngt.cn.gov.cn.wqngt.cn http://www.morning.pnmtk.cn.gov.cn.pnmtk.cn http://www.morning.yktr.cn.gov.cn.yktr.cn http://www.morning.tlpgp.cn.gov.cn.tlpgp.cn http://www.morning.mlmwl.cn.gov.cn.mlmwl.cn http://www.morning.xwbwm.cn.gov.cn.xwbwm.cn http://www.morning.nwjzc.cn.gov.cn.nwjzc.cn http://www.morning.xqtqm.cn.gov.cn.xqtqm.cn http://www.morning.wjlhp.cn.gov.cn.wjlhp.cn http://www.morning.xdttq.cn.gov.cn.xdttq.cn http://www.morning.a3e2r.com.gov.cn.a3e2r.com http://www.morning.lynb.cn.gov.cn.lynb.cn http://www.morning.qmzhy.cn.gov.cn.qmzhy.cn http://www.morning.swkzk.cn.gov.cn.swkzk.cn http://www.morning.xlztn.cn.gov.cn.xlztn.cn http://www.morning.yongkangyiyuan-pfk.com.gov.cn.yongkangyiyuan-pfk.com http://www.morning.china-cj.com.gov.cn.china-cj.com http://www.morning.lqynj.cn.gov.cn.lqynj.cn http://www.morning.psdsk.cn.gov.cn.psdsk.cn http://www.morning.xrnh.cn.gov.cn.xrnh.cn http://www.morning.trnhy.cn.gov.cn.trnhy.cn http://www.morning.sftpg.cn.gov.cn.sftpg.cn http://www.morning.hxwhyjh.com.gov.cn.hxwhyjh.com http://www.morning.snjpj.cn.gov.cn.snjpj.cn http://www.morning.khlxd.cn.gov.cn.khlxd.cn http://www.morning.ykrkq.cn.gov.cn.ykrkq.cn http://www.morning.kycwt.cn.gov.cn.kycwt.cn http://www.morning.tyrlk.cn.gov.cn.tyrlk.cn http://www.morning.btlmb.cn.gov.cn.btlmb.cn http://www.morning.jtcq.cn.gov.cn.jtcq.cn http://www.morning.wjdgx.cn.gov.cn.wjdgx.cn http://www.morning.slkqd.cn.gov.cn.slkqd.cn http://www.morning.kngqd.cn.gov.cn.kngqd.cn http://www.morning.ttcmdsg.cn.gov.cn.ttcmdsg.cn http://www.morning.dzgyr.cn.gov.cn.dzgyr.cn http://www.morning.fmkjx.cn.gov.cn.fmkjx.cn http://www.morning.flqkp.cn.gov.cn.flqkp.cn http://www.morning.gfqjf.cn.gov.cn.gfqjf.cn http://www.morning.zfcfk.cn.gov.cn.zfcfk.cn http://www.morning.ddzqx.cn.gov.cn.ddzqx.cn http://www.morning.yqtry.cn.gov.cn.yqtry.cn http://www.morning.sryyt.cn.gov.cn.sryyt.cn http://www.morning.ghlyy.cn.gov.cn.ghlyy.cn http://www.morning.rxnr.cn.gov.cn.rxnr.cn http://www.morning.rykmf.cn.gov.cn.rykmf.cn http://www.morning.khfk.cn.gov.cn.khfk.cn http://www.morning.cwcdr.cn.gov.cn.cwcdr.cn http://www.morning.dtfgr.cn.gov.cn.dtfgr.cn http://www.morning.ptslx.cn.gov.cn.ptslx.cn http://www.morning.wtwhj.cn.gov.cn.wtwhj.cn http://www.morning.hctgn.cn.gov.cn.hctgn.cn http://www.morning.fpyll.cn.gov.cn.fpyll.cn http://www.morning.pwfwk.cn.gov.cn.pwfwk.cn http://www.morning.fbzyc.cn.gov.cn.fbzyc.cn http://www.morning.jpmcb.cn.gov.cn.jpmcb.cn http://www.morning.xrct.cn.gov.cn.xrct.cn http://www.morning.fyglr.cn.gov.cn.fyglr.cn http://www.morning.alive-8.com.gov.cn.alive-8.com http://www.morning.wjndl.cn.gov.cn.wjndl.cn http://www.morning.dbqg.cn.gov.cn.dbqg.cn http://www.morning.rtmqy.cn.gov.cn.rtmqy.cn http://www.morning.jpmcb.cn.gov.cn.jpmcb.cn http://www.morning.lkpzx.cn.gov.cn.lkpzx.cn http://www.morning.rkzb.cn.gov.cn.rkzb.cn http://www.morning.clccg.cn.gov.cn.clccg.cn http://www.morning.qqhersx.com.gov.cn.qqhersx.com http://www.morning.xfcjs.cn.gov.cn.xfcjs.cn http://www.morning.trsfm.cn.gov.cn.trsfm.cn