`
felixour
  • 浏览: 32912 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

Netjava Lesson 16 重温旧识——哈夫曼树

 
阅读更多

2013.09.24

 

今天我们来重温一下以前学习的关于哈夫曼树的构建。

 

回顾一下,我们给定了一些节点,每个节点都有对应的数值,现在我们要用这些节点生成二叉树,而且要求加权路径最小,即权值乘以节点对应的数值,然后再求和,我们要求的是这个最小。比如我们现在有64个节点,要是按照平时,我们会将64个节点一字排开,然后两两生成父节点,然后父节点再生父节点,直至生成以二叉树。但是这样的话我们显然可以看出加权路径不是最优的,因为大数值点和小数值点在一个水平上。我们如果要实现加权路径最小,那么我们就更希望小数值节点在下面,而大数值节点在上面。哈夫曼树的构建正是基于这一原理,实现了对字符串的压缩,进而可以去实现对于文件的压缩。

 

在进行压缩前,我们先定义一个节点类:

public class Node {
	Node left;//左节点
	Node right;//右节点
	char ch;//节点对应的字符
	int num;//数值
}

 

还有就是编码类:

public class Code {
	private char ch;// 字符
	private int num;// 出现次数
	private String str;// 对应编码
}

 

当然基础类还会有构造方法和get,set方法,我们这里就不一一阐述了。

 

然后我们就要来构建哈夫曼树:
首先我们定义两个队列:

ArrayList<Code> code = new ArrayList<Code>();
ArrayList<Node> node = new ArrayList<Node>();

code用于存放编码,node用于存放节点。

 

下面我们就要开始进行哈夫曼树的构建了:
1、我们要开始字符串的统计,并将字符和其出现次数生成编码存到编码队列里:

	public void countString(String str) {
		char[] ch = str.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			boolean bol = true;
			for (int j = 0; j < code.size(); j++) {
				if (ch[i] == code.get(j).getCh()) {
					code.get(j).setNum(code.get(j).getNum() + 1);
					bol = false;
				}
			}
			if (bol) {
				code.add(new Code(ch[i]));
			}
		}
	}

 

2、创建哈夫曼树:

	public void creatTree() {
		for (int i = 0; i < code.size(); i++) {
			node.add(new Node(code.get(i).getCh(), code.get(i).getNum()));// 将叶子节点输入
		}
		sortNode();// 进行编码排序
		while (node.size() > 1) {
			Node temp = new Node(node.get(0), node.get(1), node.get(0).getNum()
					+ node.get(1).getNum());
			node.remove(0);
			node.remove(0);
			node.add(temp);
			sortNode();
		}
	}

 

 其中用到sortNode方法,是用来对节点对应的数值进行一个排序:

	private void sortNode() {
		for (int i = 0; i < node.size(); i++) {
			for (int j = i; j < node.size(); j++) {
				if (node.get(i).getNum() > node.get(j).getNum()) {
					Node node1 = node.get(i);
					Node node2 = node.get(j);
					node.set(i, node2);
					node.set(j, node1);
				}
			}
		}
	}

 

3、根据节点生成码表:

	public void creatCodeList() {
		String str = new String();
		codeList(node.get(0), str);
		for (int i = 0; i < code.size(); i++) {
			System.out.println(code.get(i).getCh() + "   "
					+ code.get(i).getStr());
		}
	}

 

这里我们用递归来生成码表,写了codeList方法:

	private void codeList(Node node, String str) {
		if (node.left == null && node.right == null) {
			for (int i = 0; i < code.size(); i++) {
				if (code.get(i).getCh() == node.getCh()) {
					code.get(i).setStr(str);
				}
			}
		}
		if (node.left != null) {
			codeList(node.left, str + "0");
		}
		if (node.right != null) {
			codeList(node.right, str + "1");
		}
	}

 

4、根据码表生成最终编码:

	public String printCodeList(String s) {
		char[] ch = s.toCharArray();
		String str = new String();
		for (int i = 0; i < ch.length; i++) {
			for (int k = 0; k < code.size(); k++) {
				if (code.get(k).getCh() == ch[i]) {
					str += code.get(k).getStr();
					break;
				}
			}
		}
		System.out.println(str);
		return str;
	}

 

5、根据码表和生成的编码还原编码:

	public String restoreCodeList(String codeStr) {
		String str = new String();
		for (int i = 0; i < codeStr.length(); i++) {
			for (int j = i; j <= codeStr.length(); j++) {
				String temp = codeStr.substring(i, j);
				for (int k = 0; k < code.size(); k++) {
					if (code.get(k).getStr().equals(temp)) {
						str += code.get(k).getCh();
						i = j;
					}
				}
			}
		}
		System.out.println(str);
		return str;
	}

 

这样,哈夫曼树的构建就完成了,下一次我们就会讲如何利用哈夫曼树实现文件的压缩,敬请期待~

分享到:
评论

相关推荐

    课设——哈夫曼树的源代码

    哈夫曼树(Huffman Tree),也称为最优二叉树,是一种特殊的二叉树结构,广泛应用于数据压缩领域。在信息编码中,哈夫曼编码是一种可变长度的前缀编码,它根据字符出现的频率分配不同的二进制编码,频率高的字符编码...

    数据结构课程设计——哈夫曼树

    在数据结构的学习中,哈夫曼树(Huffman Tree)是一种非常重要的数据结构,它在数据压缩、编码优化等领域有着广泛的应用。哈夫曼树,也称为最优二叉树,是一种带权路径长度最短的二叉树。在这个数据结构课程设计中,...

    数据结构课设——哈夫曼树

    在这个课设中,我们关注的是哈夫曼树(Huffman Tree),一种在数据压缩领域广泛应用的数据结构。哈夫曼树,也称为最优二叉树,是通过哈夫曼编码实现数据压缩的关键工具。下面将详细阐述哈夫曼树的概念、构建过程、...

    树的应用——哈夫曼编码

    树的应用——哈夫曼编码 二、 实验内容: 利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。 从...

    数据结构——哈夫曼树(自己编的)

    哈夫曼树 基本功能: (1) 从文件中读出一篇英文文章,包含字母和空格等字符。 (2) 统计各个字符出现的频度。 (3) 根据出现的频度,为每个出现的字符建立一个哈夫曼编码,并输出。 (4) 输入一个字符串,为其...

    C++课程设计——哈夫曼树.txt

    设计内容: 欲发一封内容为AABBCAB ……(共长 100 字符,其中:A 、B 、C 、D 、E 、F分别有7 、9 、12 、22 、23、27个)的电报报文,实现哈夫曼编码。

    数据结构——哈夫曼编码

    它的核心思想是通过构建一个特殊的二叉树——哈夫曼树(Huffman Tree),来为数据的各个符号分配最短的编码,使得频率高的符号编码较短,频率低的符号编码较长,从而实现数据的平均码长最小化,达到压缩数据的目的。...

    最优二叉树——哈夫曼树.doc

    树结构的特点是:它的每一个结点都可以有不止一个直接后继,除根结点外的所有结点都有且只有一个直接前趋。

    hafuman.rar_huffman java_huffman java code_java 哈夫曼_哈夫曼树的

    哈夫曼编码是一种高效的数据压缩方法,它基于一种特殊的二叉树——哈夫曼树(Huffman Tree)来实现。在Java编程中,理解和实现哈夫曼编码是数据结构和算法学习的重要一环。本教程将详细介绍哈夫曼树的构建过程以及其...

    数据结构课程设计——哈夫曼编/译码器

    在这个“数据结构课程设计——哈夫曼编/译码器”项目中,我们将深入学习哈夫曼编码的原理和实现。哈夫曼编码的过程主要包括以下几个步骤: 1. **统计字符频率**:首先,我们需要统计输入文本中每个字符出现的次数,...

    java 哈夫曼树及哈夫曼树的应用

    在Java中实现哈夫曼树,我们可以分为以下几个步骤: 1. **哈夫曼编码**:哈夫曼编码是哈夫曼树的基础,它是为每个字符分配一个唯一的二进制码,使得字符出现频率越高,其编码越短。哈夫曼编码的过程是通过构造...

    《数据结构》实验——哈夫曼编码

    哈夫曼编码是一种高效的数据压缩方法,源自于数据结构中的树形数据结构,主要用于无损数据压缩。在《数据结构》这本教材中,哈夫曼编码是重要的章节之一,通常由人民邮电出版社出版的教材会详细讲解这一概念。在进行...

    哈夫曼树及哈夫曼编码的实现(java)

    `HuffmanTree.java`包含了哈夫曼树的实现,包括节点类和构建树的方法,而`Node.java`则可能只包含哈夫曼树的节点定义。这些代码示例可以作为学习和理解哈夫曼编码及其应用的基础。 总结来说,哈夫曼树和哈夫曼编码...

    C语言实现哈夫曼树的构建

    哈夫曼树的构建与C语言实现 哈夫曼树是一种特殊的二叉树,它的权值越小,越靠近根节点。哈夫曼树的构建是数据压缩和编码的重要组件。下面是哈夫曼树的构建与C语言实现的相关知识点: 一、哈夫曼树的定义 哈夫曼...

    哈夫曼树压缩算法实现

    哈夫曼树(Huffman Tree),也称为最优二叉树,是数据压缩领域中的一个重要概念。它是基于贪心策略的一种数据结构,用于构建一种特殊的二叉树,使得带权路径长度最短,从而达到编码效率最高。哈夫曼树的核心思想是...

    哈夫曼树 课程设计 实验报告

    哈夫曼树是一种在计算机科学中广泛使用的数据结构,尤其在数据压缩领域有着重要的应用。本实验报告主要探讨了如何运用哈夫曼树对文本文件进行编码和解压缩,以实现无损数据压缩。 首先,我们需要理解哈夫曼树的基本...

    哈工大数据结构——哈夫曼编码

    哈夫曼树,也称为最优二叉树或最小带权路径长度树,是一棵特殊的二叉树,其中每个叶子节点代表一个需要编码的字符,而内部节点(非叶子节点)则表示合并两个频率较低的字符节点形成的新的频率节点。构建哈夫曼树的...

    数据结构哈夫曼树PPT学习教案.pptx

    "数据结构哈夫曼树PPT学习教案.pptx" 哈夫曼树是一种特殊的二叉树,它的带权路径长度最小。哈夫曼树的构造是数据结构中的一种重要算法,广泛应用于数据压缩、编码和决策树等领域。 一、基本术语 在哈夫曼树中,...

Global site tag (gtag.js) - Google Analytics