哈夫曼树又称为最优二叉树

1、路径和路径长度

在一棵树中,从一个节点往下可以达到的孩子或者子孙节点之间的通路称为路径。通路中分支的数目称为路径长度。若规定根节点的层数为1,则从根节点
到第L层节点的路径长度为L-1.

2、节点的权和带权路径长度

若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。

3、树的带权路径长度

树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。


4、哈夫曼树的构造:

假设有n个权值,则构造出的哈夫曼树有N个叶子节点。n个权值分别设为w1、w2……wn,则哈夫曼树的构造规则为:

1、将w1、w2……wn看成是有n棵树的森林(每棵树仅有一个节点);
2、在森林中选出两个根节点权值最小的树合并,作为一棵新树的左、右子树,且新树的根节点权值为其左、右子树根节点权值之和;
3、从森林中删除选取的两棵树,并将新树加入森林;
4、重复2、3步,直到森林中只剩一棵树为止,该树即为所求的的哈夫曼树。


5、基本性质:

具有n个叶子节点的哈夫曼树,一共需要2n-1个叶子节点。


6、java实现构造哈夫曼树以及对哈夫曼树的广度优先遍历:

Node.java


/*** 哈夫曼树的结点类* @author lmb**/
public class Node<T> implements Comparable<Node<T>> {private T data;private double weight;private Node<T> left;private Node<T> right;public Node(T data, double weight) {super();this.data = data;this.weight = weight;}public T getData() {return data;}public void setData(T data) {this.data = data;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}public Node<T> getLeft() {return left;}public void setLeft(Node<T> left) {this.left = left;}public Node<T> getRight() {return right;}public void setRight(Node<T> right) {this.right = right;}public String toString(){return "data : " + this.data + "; weight : " + this.weight;}@Overridepublic int compareTo(Node<T> other) {if (other.getWeight() > this.getWeight()) {return 1;}if (other.getWeight() < this.getWeight()) {return -1;}return 0;}}

HuffmanTree.java

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;import edu.emory.mathcs.backport.java.util.Collections;public class HuffmanTree<T> {public static void main(String[] args){List<Node<String>> list = new ArrayList<Node<String>>();list.add(new Node<String>("a",9));list.add(new Node<String>("b",5));list.add(new Node<String>("c",3));list.add(new Node<String>("d",7));list.add(new Node<String>("e",8));list.add(new Node<String>("f",6));//构造一棵哈夫曼树Node<String> root = createTree(list);//广度优先遍历刚刚构造的哈夫曼树List<Node<String>> nodes = breadth(root);for (int i = 0; i < nodes.size(); i++) {System.out.println(nodes.get(i));}}//创建哈夫曼树public static <T> Node<T> createTree(List<Node<T>> nodes){while(nodes.size() > 1){Collections.sort(nodes);Node<T> left = nodes.get(nodes.size() - 1);//左节点Node<T> right = nodes.get(nodes.size() - 2);//右节点//父节点Node<T> parent = new Node<T>(null,left.getWeight() + right.getWeight());//利用左右节点构造父节点parent.setLeft(left);parent.setRight(right);//从森林中删除所选的两棵树,并将新树加入森林nodes.remove(left);nodes.remove(right);nodes.add(parent);          }return nodes.get(0);}public static <T> List<Node<T>> breadth(Node<T> root){List<Node<T>> list = new ArrayList<Node<T>>();Queue<Node<T>> queue = new ArrayDeque<Node<T>>();//如果根节点不为空,将根节点加入队列if (root != null) {queue.offer(root);}while(!queue.isEmpty()){//将队列前端元素节点加入list中(使用但不移出)list.add(queue.peek());//获取并移出队列中的元素节点Node<T> node = queue.poll();//如果节点的左子树存在,将其加入队列if (node.getLeft() != null) {queue.offer(node.getLeft());}//如果节点的右子树存在,将其加入队列if (node.getRight() != null) {queue.offer(node.getRight());}}return list;}}

运行结果:

data : null; weight : 38.0
data : null; weight : 16.0
data : null; weight : 22.0
data : null; weight : 8.0
data : e; weight : 8.0
data : a; weight : 9.0
data : null; weight : 13.0
data : c; weight : 3.0
data : b; weight : 5.0
data : f; weight : 6.0


附录:java.util.Queue用法

队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

在队列这种数据结构中,最先插入的元素将是最先被删除的元素;反之最后插入的元素将是最后被删除的元素,因此队列又称为“先进先出”(FIFO—first in first out)的线性表。

在java5中新增加了java.util.Queue接口,用以支持队列的常见操作。该接口扩展了java.util.Collection接口。

Queue使用时要尽量避免Collection的add()和remove()方法,而是要使用offer()来加入元素,使用poll()来获取并移出元素。它们的优点是通过返回a.u值可以判断成功与否,add()和remove()方法在失败的时候会抛出异常。 如果要使用前端而不移出该元素,使用element()或者peek()方法。

值得注意的是LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。

【大话数据结构算法】哈夫曼树相关推荐

  1. 数据结构(哈夫曼树+KMP)之 数据加密+解密

    数据结构(哈夫曼树+KMP)之 数据加密+解密 原理:参考趣学数据结构 代码: #include<stdio.h> #include<stdlib.h> #define N 1 ...

  2. 数据结构“基于哈夫曼树的数据压缩算法”的实验报告

    一个不知名大学生,江湖人称菜狗 original author: jacky Li Email : 3435673055@qq.com Last edited: 2022.11.20 目录 数据结构& ...

  3. 数据结构 基于哈夫曼树的数据压缩算法

    数据结构 基于哈夫曼树的数据压缩算法 实验目的 实验内容 实验提示 实验代码 实验小结 实验目的 1.掌握哈夫曼树的构造算法. 2.掌握哈夫曼编码的构造算法. 实验内容 问题描述 输入一串字符串,根据 ...

  4. 2020-10-1 //严蔚敏《数据结构》 //赫夫曼树及其应用:创建顺序赫夫曼树创建及得到赫夫曼编码

    //严蔚敏<数据结构> //赫夫曼树及其应用:创建顺序赫夫曼树创建及得到赫夫曼编码 //(从叶子结点到根逆向求每个字符的赫夫曼编码)以及(无栈非递归遍历赫夫曼树,求赫夫曼编码) //自学中 ...

  5. 数据结构与算法 / 霍夫曼树、霍夫曼编码和解码

    一. 诞生原因 找出存放一串字符所需的最少的二进制编码. 二. 构造方法 首先统计出每种字符出现的频率,即:概率.权值. 例如:频率表 A:60,    B:45,   C:13   D:69   E ...

  6. 数据结构与算法--哈夫曼树及其应用

    一.哈夫曼树的基本概念 1) 路径: 从树中一个结点到另一个结点之间的分支构成这两个结点间的路径 2) 结点的路径长度: 两结点间路径上的分支数           3) 树的路径长度:从树根到每一个 ...

  7. 数据结构与算法——赫夫曼树基本实现

    目录 一.赫夫曼树 1.1 基本介绍 1.2 赫夫曼树创建步骤图解 1.3  代码实现 二.赫夫曼编码 2.1 基本介绍 2.1.1  通讯领域 - 定长编码 - 举例说明 2.1.2  通讯领域 - ...

  8. 数据结构与算法(赫夫曼树,赫夫曼编码)

    赫夫曼树 基本介绍: (1)给定n个权值作为n给叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称哈夫曼树(HuffmanTree),还有的树翻译为霍夫 ...

  9. 数据结构教程—哈夫曼树的构造算法

    哈夫曼树算法如下 (1)根据给定的n个权值,使对应节点构成n棵二叉树的森林,其中每棵二叉树都只有一个根节点,其左右子树均为空. (2)在森林中选取两棵节点权值最小的子树分别作为左右子树构造一棵新的二叉 ...

  10. 数据结构与算法--哈夫曼树应用

    第1关:统计报文中各个字符出现的次数 任务描述 本关任务: 给定一串文本,统计其中各个字符出现的次数: 测试说明 平台会对你编写的代码进行测试: 测试输入:` abcdeabcdeabcdabcdab ...

最新文章

  1. 动态注册客户端脚本的方法
  2. VS2013关于“当前不会命中断点源代码与原始版本不同”的BUG
  3. 3950双层交换机生成树协议
  4. linux 好用的命令积累
  5. 计算机办公软件技能大赛试题,第七届计算机技能大赛办公软件操作比赛顺利举行...
  6. 小孔成像实验探究的软件_【亲子实验】科学小制作:神秘小潜艇科学小论文作品在科学课(小学版)2004年第5期发表,科学小发明潜水艇与沉浮子...
  7. android布局中上下对齐,android – 如何使用相对布局垂直对齐列表中的项?
  8. 当SQL Server爱上Linux:AVAILABILITY_MODE 和 DataGuard 的实践差距
  9. node.js与python_Node.js与Python
  10. html表单查重,毕业论文的表格会被查重吗?
  11. OA系统中的任务管理
  12. 蓝牙音频中Classic Audio和LEAudio对比和区别
  13. 高效能人士的七个习惯读后感与总结概括-(第二章)
  14. c语言abcd=(ab cd),汇编语言编程求具有abcd=(ab+cd)^2 性质的4 位数并输出。例如3025=(30+25)2。(不是C语言)...
  15. error: [debug/qrc_resource.cpp] Error 1
  16. css中子元素设置margin-top会影响到父元素
  17. android carlife 源码,CarLife开发总结
  18. gspca 摄像头驱动的移植(ZC3XX)
  19. C++编程规范 头文件格式 和 函数注释格式
  20. iframe嵌套微信公众号文章

热门文章

  1. JavaScript--在页面的下拉框控件中遍历出日期--先天下能力工场
  2. Hashtable排序
  3. DATAGUARD配置错误的解决日志
  4. Eclipse 中 按 Ctrl+Shift+F 格式化代码时每行容纳的字符数
  5. android开源许可证
  6. [译] Go: 理解 Sync.Pool 的设计
  7. MySQL—通过Adjacency List(邻接表)存储树形结构
  8. 分布式离线计算—Spark—SparkStreaming
  9. Python中生成一个指定长度的随机字符串实现示例
  10. mvc根据绝对路径下载文件