`
剑&箫
  • 浏览: 53571 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

哈夫曼树小结

    博客分类:
  • Java
阅读更多
所谓哈夫曼树,又称为最优二叉树,要了解哈夫曼树,首先先来了解几个概念。树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,路径上分支数目称为路径长度。树的长度是指从根结点到每一个叶子结点的路径长度之和。结点的带权路径长度为从从该结点到根结点之间的路径长度与结点上的权值的乘积。哈夫曼树就是带权路径长度最小的二叉树。现在我们可以根据给的任意一个整型数组构造一颗哈夫曼树,构造的思路是将数组中的每一个元素构造成结点对象,然后把每一个结点当成一棵树,将所有结点当成一片森林。然后每次从所有结点中取两个最小的结点,比较小的作为左子结点,比较大的作为右子结点,它们的和作为父结点构成一颗二叉树,然后把取出的这两个结点删除,将父结点放入剩下的结点中再重复以上过程直到最后只剩下一个结点,该结点即为哈夫曼树的根结点。从以上过程看,关键在于对数组的排序以及接收新的数组,这里用到java里面提供的优先队列PriorityQueue<E>,该队列的作用是将任意无序数组元素加入到该队列中,在该队列中这些元素会按某种顺序排好,只要按顺序取出就行了。查阅API文档可知,该队列定义了六个构造器,这里用到文档中的第四个构造器实例化一个该队列的对象,由该构造器的参数定义一个类来实现该参数接口类型,代码如下所示:
/**
* 实现比较对象类型接口类,该类作为优先队列的构造方法的参数传入
* @author lenovo
*
*/
class MyComparator implements Comparator<TreeNode>{

public int compare(TreeNode o1, TreeNode o2){

return (Integer)o1.getObj() - (Integer)o2.getObj();

}

public boolean equals(Object obj){
return false;
}

}

实现了该接口之后就可以实例化一个该队列的对象,然后将数组元素添加到该队列中,最后遍历队列,每次取出最小的两个元素,按上面思路就可以构造出哈夫曼树,具体代码如下所示:

/**
* 创建最优二叉树的方法
* @param arr:传入的数组
* @param TreeNode:返回根结点
*/
public TreeNode createHuffman(int[] arr){
//实例化一个优先队列对象
PriorityQueue<TreeNode> queue = new PriorityQueue<TreeNode>(11,new MyComparator());
TreeNode root=null;
//遍历数组,将数组元素构建成结点,并添加到队列中
for (int i=0;i<arr.length;i++){
//创建结点
TreeNode node = new TreeNode(arr[i]);
//将结点添加到队列中
queue.add(node);
}

//遍历队列,每次取出两个最小元素作为叶子结点,它们的和作为父结点建立二叉树,
//并从队列中删除这两个元素,同时把它们的父结点添加到队列中
while(queue.size()!=1){
//同时取两个最小元素
TreeNode node1 = queue.poll();
TreeNode node2 = queue.poll();

//根据取得的元素创建父结点
TreeNode fnode = new TreeNode((Integer)node1.getObj()+(Integer)node2.getObj());

//建立引用关系
if ((Integer)node1.getObj()<(Integer)node2.getObj()){//如果node1小于node2,则node1作为左子结点,node2作为右子结点
fnode.setLchild(node1);
fnode.setRchild(node2);
node1.setParent(fnode);
node2.setParent(node2);
}else {//如果node1大于于node2,则node1作为右子结点,node2作为左子结点
fnode.setLchild(node2);
fnode.setRchild(node1);
node1.setParent(fnode);
node2.setParent(node2);
}

//将父结点添加到队列中
queue.add(fnode);
root = fnode;

}
return root;
}
哈夫曼树生成之后,从根结点开始,对左子树分配代码“1”,右子树分配代码“0”,一直到达叶子结点为止,然后将从树根沿每条路径到达叶子结点的代码排列起来,就可以得到哈夫曼编码了,具体代码如下所示:
/**
* 根据根结点创建哈夫曼编码
* 规则:左子结点为:1,右子结点为:0
* @param root:根结点
*/
public void createCode(TreeNode root,String code){
//首先是确定各结点的路径
//得到子结点
TreeNode Lchild = root.getLchild();

TreeNode Rchild = root.getRchild();
//打印叶子节点
if (Lchild==null&&Rchild==null){
System.out.println(root.getObj()+"的编码为:"+code);
}

if (Lchild!=null){
//递归
createCode(Lchild,code+"1");
}
if (Rchild!=null){
//递归
createCode(Rchild,code+"0");
}

}
通过以下的主函数对上面的方法进行验证,主函数为:
/**
* 程序入口
* @param args
*/
public static void main(String args[]){
//实例化一个数组
int[] a = {8,6,3,4,9};
HuffmanTree ht = new HuffmanTree();
TreeNode root = ht.createHuffman(a);
ht.printTree(root);
System.out.println();
ht.createCode(root,"");

}
运行结果为:
30 13 6 7 3 4 17 8 9
6的编码为:11
3的编码为:101
4的编码为:100
8的编码为:01
9的编码为:00

通过检验可知结果正确,这就是自己对哈夫曼树的理解,如果有不正确的地方欢迎指正。
1
3
分享到:
评论

相关推荐

    C语言编码哈夫曼树

    //m为结点数,一棵有n个叶子结点的哈夫曼树共有2n-1个结点,可以存储在一个大小为2n-1的一维数组中 HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用 //--------初始化哈弗曼树------- for(p=HT+1,i=...

    课程设计哈夫曼树的应用

    一、课程设计题目:哈夫曼树应用 二、课程设计要求: 1) 从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在内存中的哈夫曼树以...6.小结 14 参考文献 15 附录:源程序代码 16

    数据结构C#哈夫曼树

    在哈夫曼树中,权值较小的节点通常位于较浅的层次,权重较大的节点则在较深的层次。这个特性使得频繁出现的字符编码更短,从而降低数据的存储和传输成本。 2. **哈夫曼编码** 哈夫曼编码是为每个字符分配一个唯一...

    哈夫曼树 c数据结构

    将已在内存中的哈夫曼树以直观的方式(树或凹凸表形式)显示在屏幕上,同时将此字符形式的哈夫曼树写入文件treeprint中。 实现提示: 1、用户界面可以设计为“菜单”方式:显示上述功能号,再加上“E”表示结束运...

    构造哈夫曼树之后,求每一个字符的编码需要走一条从叶子结点到根结点的路径

    在哈夫曼树中,没有度为1的结点,结点总数是n0+n2(其中n0表示二叉树中度为0的结点数,n2表示度为2的结点数),而由二叉树的性质知道n0=n2+1,所以一棵哈夫曼树中结点总数是2n0-1。 由此可以得出:任何n个字符的...

    树,二叉树及其遍历,哈夫曼树课题讲解

    哈夫曼树(Huffman Tree)是一种特殊的二叉树,用于数据压缩,通过构建具有最小带权路径长度的二叉树来实现。哈夫曼编码是基于哈夫曼树生成的,频率高的字符编码较短,频率低的字符编码较长,从而实现高效的数据压缩...

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

    哈夫曼树是根据给定的权值集合构造的,它的特点是:有n个叶子结点,没有度为1的结点,总的结点数为2n-1,深度≤n-1,形态不唯一。 哈夫曼树的构造可以使用哈夫曼算法,哈夫曼算法的步骤是: 1. 根据给定的n个权值{...

    数据结构5哈夫曼树和哈夫曼编码.ppt

    哈夫曼树和哈夫曼编码是数据结构中的一种重要概念,哈夫曼树是一种特殊的二叉树,它可以用来构造最优的前缀编码。哈夫曼编码是一种变长编码方法,它可以使得总的编码长度最短。 哈夫曼树的定义是指带权路径长度最小...

    数据结构-哈夫曼树和哈夫曼编码.ppt

    哈夫曼树(Huffman Tree)是一种特殊的二叉树,它的特点是:有 n 个叶子结点,不存在度为 1 的结点,总的结点数为 2n-1,深度≤ n-1,形态不唯一。哈夫曼树的定义是:带权路径长度 WPL 最小的二叉树。哈夫曼树的构建...

    哈夫曼压缩

    利用哈夫曼编码进行信息通讯可以大大提高信道利用率,缩短信息传输时间,降低传输成本。...将已在内存中的哈夫曼树以直观的方式 (树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件treeprint中。

    数据结构 哈夫曼编码

    此外,报告还需要符合一定的格式规范,如包含目录、绪论、正文、小结、参考文献、谢辞和附录等,并满足学校对论文装订的要求。在答辩阶段,学生需要能够清晰地阐述问题的解决方法、算法思想、数据结构的选择以及测试...

    哈夫曼指导书 C语言程序设计

    3. 完成课程设计报告,包括问题分析、总体设计、详细设计、测试报告、小结和软件使用说明。 课程设计报告中,需要特别注意的是,哈夫曼树的构建和编码过程,以及如何处理码文件最后一字节的多余位信息。在处理位串...

    基于哈夫曼用户登录系统

    本文将围绕哈夫曼树(Huffman Tree)在用户登录系统中的应用,以及相关文件如AVL树(AVL Tree)等在系统中的角色进行深入探讨。 哈夫曼编码是一种特殊的二叉树结构,通常用于数据压缩,通过构建最小带权路径长度...

    哈夫曼编码实现图像压缩

    哈夫曼树是哈夫曼编码的核心结构,指所有叶子结点的二叉树中带权路径长度最小的二叉树。也称最优二叉树树的带权路径长度:从树的根节点到该节点的路径长度与该节点权的乘积之和。 哈夫曼编码实现图像压缩的基本原理...

    数据结构复习资料全.doc

    13. **哈夫曼树的结点数**:构建哈夫曼树时,除了n个叶结点,还需要n-1个内部结点,总共是n+n-1=2n-1个结点。 14. **哈夫曼树的双支结点数**:哈夫曼树的构建过程中,每次合并两个最小节点生成一个新的内部节点,...

    哈夫曼编码动态绘制小软件,是大二做的一份结课作业

    小程序提供了两种功能的哈夫曼编码方式: 一、读取本地文件的字符: 对其进行哈夫曼编码后输出编码后的文件到指定文本文件。 二、用户输入待分析字符: ... 哈夫曼树的构建过程动态显示等功能。

    第六章 树和二叉树作业及答案(100分).docx

    构造一棵哈夫曼树(6分),给出每个字符的哈夫曼编码(4分),并计算哈夫曼树的加权路径长度WPL(2分)。 (符合WPL最小的均为哈夫曼树,答案不唯一) 哈夫曼编码: 2. 假设用于通信的电文由字符集{a,b,c,d,e,f,g}中...

    大学数据结构期末考试试题(有答案)-aa72220b76c66137ee061980.doc

    4. 哈夫曼树问题:要求以7个带权结点为叶子结点生成一棵哈夫曼树,并求出该树的带权路径长度、高度、双分支结点数。 阅读算法问题部分考察了对算法的理解和分析能力。 1. algorithm分析问题:要求分析给定的算法,...

    计算机软件基础:15第四章数据结构图.doc

    本章节主要探讨了数据结构中的一个重要概念——最优二叉树,也称为哈夫曼树,这是在数据编码和压缩中非常关键的一个数据结构。 最优二叉树是一种特殊的二叉树,它的目标是最小化树中所有叶子节点的权值乘以其路径...

    CCF中学生计算机程序设计提高篇(完整版)

    2.5 哈夫曼树及其应用 2.6 二叉堆及其应用 2.7 二叉排序树及其应用.. 本章小结 第3章集合与并查集 3.1 集合与并查集...... 3.2 并查集的基本操作 3.3并查集的应用 本章小结 第4章图及其应用 4.1 图的基本概念 4.2 图...

Global site tag (gtag.js) - Google Analytics