`
wuzexin530
  • 浏览: 19026 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论
阅读更多

       还记得第一次接触哈夫曼树是在大二的数据结构课上,大家也都知道哈树的生成规则,很简单也很容易理解。给你N个带权的节点,让你生成一颗哈树,相信大部分人都没有问题。而正是这种表面看似很简单的东西,我们就容易无视。我坦白,那年数据结构的学习,对于哈树这一块,我没有敲过一行代码,更没有去想过他存在的意义以及利用哈树能解决什么样的问题。

       大三进入蓝杰,重新接触到了哈夫曼树。这个沉寂在我脑海已久且濒临消亡的知识点,仿佛又渐渐地回来了。也让我开始思考哈夫曼树存在的意义。在IT这么一个日新月异的领域,一个技术之所以能够存在,一定是有其价值的,他一定是能给我们决绝问题带来利益的。通过查找给方面的资料,发现哈弗曼的用处确实很广,尤其是在数据通信、图像处理、数据压缩等方面有着很大的用处。

       下面,我想通过手动建造一棵哈夫曼树,再次走进哈夫曼的世界。 ------

一、哈弗曼的基础知识

      大家要了解一下哈夫曼树的基础知识。网上有很多解释,度娘说的比我清楚,这里就不占用篇幅多做解释。

     下图是建造一颗哈树的过程....

二、 进入主题--------代码的实现

     

    (1)首先,定义一个树的节点类

/**
 * 哈夫曼树节点的定义
 * 
 * @author Administrator
 * 
 */
public class HuffmanNode {
	// 成员属性
	private HuffmanNode left_child = null;
	private HuffmanNode right_child = null;
	private HuffmanNode parend = null;
	// 权值
	private int obj;

	public HuffmanNode getLeft_child() {
		return left_child;
	}

	public void setLeft_child(HuffmanNode left_child) {
		this.left_child = left_child;
	}

	public HuffmanNode getRight_child() {
		return right_child;
	}

	public void setRight_child(HuffmanNode right_child) {
		this.right_child = right_child;
	}

	public HuffmanNode getParend() {
		return parend;
	}

	public void setParend(HuffmanNode parend) {
		this.parend = parend;
	}

	public int getObj() {
		return obj;
	}

	public void setObj(int obj) {
		this.obj = obj;
	}

	// 构造函数
	public HuffmanNode(int obj) {
		this.obj = obj;
	}

}

 

(2)生成一颗哈树

         这里用到了一个新的知识点---优先队列。因为哈夫曼树的构造规则是每次要取根节点权值最小的两棵树出来。所以我们必须根据这些根节点权值大小,将这些树进行排序。 优先队列恰好为我们提供了这项功能,我们通过重新定义Comparator比较器,可以设定自己想要的排序规则,十分方便。

Comparator<HuffmanNode> comparator = new Comparator<HuffmanNode>() {

			@Override
			public int compare(HuffmanNode o1, HuffmanNode o2) {
				int numbera = o1.getObj();
				int numberb = o2.getObj();
				if (numberb < numbera) {
					return 1;
				} else if (numberb > numbera) {
					return -1;
				} else {
					return 0;
				}

			}
		};

 

核心语句----哈树的生成

              从森林中每次取根节点权值最小的两棵树出来,形成一棵新树,其权值为两树根绝点权值之和。并将这两棵树分别作为新树的左右子树。循环往复,知道深林中只剩下1棵树。那么,这棵树就是我们要找的哈夫曼树。

/**
	 *  生成哈夫曼树的方法
	 * @param queue 优先队列
	 */
	private void creathuffman(PriorityQueue<HuffmanNode> queue) {
		while (queue.size() != 1) {
			// 取得两个最小的节点
			HuffmanNode node1 = queue.poll();
			HuffmanNode node2 = queue.poll();
			// 生成一个新的节点
			HuffmanNode node3 = new HuffmanNode(node1.getObj() + node2.getObj());
			node3.setLeft_child(node1);
			node3.setRight_child(node2);
			queue.add(node3);
		}
	}

 

(3)打印所生成的哈树(通过先序遍历)

        

// 打印哈夫曼树的方法
	private void printhuffman(HuffmanNode rootnode) {
		// 指定根节点,从根节点开始找
		HuffmanNode temp = rootnode;
		// 打印根节点的值
		System.out.print("【"+temp.getObj()+"】" + "  ");
		if (rootnode.getLeft_child() != null) {
			temp = rootnode.getLeft_child();
			// 递归调用自己,表示只要左节点不为空,就把左节点作为新的根节点继续上边步奏
			printhuffman(temp);
		}
		if (rootnode.getRight_child() != null) {
			temp = rootnode.getRight_child();
			printhuffman(temp);// 同上
		}
	}

 

         至此,我们的哈夫曼树的生成过程已经演示完毕。刚才也说了,哈夫曼树的用处还有很多,我们能够创建他,也只是完成其中最基础的要求,我们不能止步于此。当然,我们不能认为这些东西很简单,就去轻视他,自己没有动手做过,你是不会知道什么叫做说着简单做着难的。

          好啦, 之后我们会通过一个文件压缩程序的演示,其中包括了哈弗曼编码的生成,对象的序列化,文件的读出与写入等问题,跟大家进一步分享哈弗曼在数据编码上的用途。 

  • 大小: 28.4 KB
分享到:
评论

相关推荐

    c语言实现的哈弗曼树

    - 实验目的:介绍为什么要学习和使用哈弗曼树,以及在数据压缩中的作用。 - 实验原理:详细解释哈弗曼树的构造方法和编码解码过程。 - 实现细节:列出C语言实现的关键代码片段,如节点结构体定义、优先队列的实现...

    hfm.rar_哈弗曼 编码 译码

    - 接着,使用优先队列(通常用最小堆实现)来存储这些节点,每次取出频率最小的两个节点合并成一个新的节点,新节点的频率是两个子节点频率之和,将新节点再次插入队列。 - 这个过程重复,直到队列中只剩下一个...

    多媒体技术之哈弗曼编码实验报告(doc 7页).pdf

    【哈弗曼编码】是一种高效的无损数据压缩方法,它基于概率分布构建最优的前缀编码。...通过这样的实验,学生不仅可以学习到Matlab的编程技巧,还能深入理解哈弗曼编码的理论和应用,同时提升独立解决问题的能力。

    hafuman.zip_hafuman 解码

    哈弗曼编码是一种高效的数据压缩方法,...在学习哈弗曼编码时,了解其基本原理、构建过程以及如何实现编码和解码是非常重要的。通过实践编写或理解相关的程序,能够加深对这一数据压缩技术的理解,提升解决问题的能力。

    数据结构课程设计-哈夫曼

    通过这个课程设计,学生能够体验到理论知识转化为实际应用的过程,对今后的学习和工作有着重要的指导意义。 总之,哈弗曼编码是数据压缩的重要方法,通过构建哈弗曼树来优化编码,有效提高了数据传输和存储的效率。...

    数据结构课程设计_哈夫曼编解码(代码+实验报告)

    新节点作为父节点,两个子节点作为其叶子节点,再次插入优先队列。重复此过程直到队列只剩下一个节点,即得到哈夫曼树。 3. **生成哈夫曼编码**:从哈夫曼树的根节点开始,左子节点表示0,右子节点表示1,自底向上...

    霍夫曼编码

    霍夫曼编码是一种高效的数据压缩方法,主要用于无损数据压缩。...通过学习和实践霍夫曼编码,可以加深对数据结构、算法以及位操作的理解,这些技能在处理大数据、网络传输和文件存储等领域都有着广泛的应用。

Global site tag (gtag.js) - Google Analytics