闲来无事写写-Huffman树的生成过程
前言:最近项目上一直没事干,感觉无聊到了极点,给自己找点事做,补一下大学没有完成的事情,写一个huffman算法Java版的,学校里面写过c语言的。
因为很久没搞数据结构和算法这方面了(现在搞Java web,真心感觉没什么挑战啊),代码写的一般,边听歌边写,3小时,不知道为什么现在效率这么低,写习惯了
xml配置,感觉纯写算法代码手生的紧,悲呼唉哉!
1、哈夫曼树:
给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree)
2、生成过程:
1. 在n个权值里面首先寻找最小的两个权值作为子节点,开始生成第一棵子树;
2.将新子树的父节点作为一个新的权值与剩余的权值继续做比较,选出最小的两个权值继续构造新子树;
3.依次进行,直到最后一棵子树生成;
4.这时候,最后一棵子树的根节点就是整个哈夫曼树的根节点,从此根节点开始遍历,就能遍历完整个哈夫曼树。
3、图形表示:
假设有6个权值:1、2、3、4、5、6,生成哈夫曼树的过程如下:


依次下去...


这样,最终得到的父节点21就是哈夫曼树的根节点,遍历树的话,
c/c++就是:root->left root->right就可以通过递归的方式从root节点访问到最后一个子节点。
Java就是: root.left root.right通过递归从root访问到最后一个子节点。
当然,二叉树的遍历不止递归一种方法,递归是最有效率的一种,还可以通过数据结构里面堆/栈的方式进行遍历。
下面是我写的实现哈夫曼树的Java代码(为了完成功能,绝壁不是优秀的,但可以方便看懂)
注:储存权值使用了List列表,随时增或者删方便一点。
import java.util.ArrayList;
import java.util.List; class Node
{
int weight;
Node left,right,parent;
public Node(int weight)
{
this.weight=weight;
}
}
public class Huffman {
private static List<Node> list=new ArrayList<Node>();
public static Node root;
public void insert(Node node)
{
//按照插入排序的方式将节点有序插入list
if(list.size()==0){
list.add(node);
return;
}
int size=list.size();
for(int i=0;i<size;)
{
if(list.get(i).weight<node.weight){
i++;
if(i>=list.size())
list.add(node);
}
else
{
//交换位置
list.add(list.get(list.size()-1));
for(int j=list.size()-1;j>i;j--)
{
list.set(j, list.get(j-1));
}
list.set(i, node);//插入新数据
return;
} } }
public Node createTree(Node n1,Node n2)
{
//返回新子树的父节点
Node parentNode=new Node(0);
parentNode.weight=n1.weight+n2.weight;
parentNode.left=n1;
parentNode.right=n2;
n1.parent=parentNode;
n2.parent=parentNode;
return parentNode;
}
public void run(List<Node> list)
{
int length=list.size();
while(length!=0)
{
if(length==1){
root=list.get(0);
return;
}
if(length==2){
root=createTree(list.get(0),list.get(1));
return;
}
Node n1=list.get(0);
Node n2=list.get(1);
Node newNode=createTree(n1,n2);
for(int i=0;i<length-2;i++)
{
//转移数据
list.set(i, list.get(i+2));
}
list.remove(length-1);
list.remove(length-2);
insert(newNode);
length=list.size();
} }
public void display(Node node)
{
if(node!=null)
{
display(node.left);
System.out.print(node.weight+"\t");
display(node.right);
}
}
public void drawTree(Node node)
{
if(node!=null)
{
//中序遍历,打算打印树形状,有些麻烦,后面改进
// if(node.parent!=null&&node.parent.left==node)
// System.out.print("/");
// if(node.parent!=null&&node.parent.right==node)
// System.out.print("\\");
System.out.print(node.weight+"\t");
drawTree(node.left);
drawTree(node.right);
}
}
public static void main(String[] args)
{
Huffman hf=new Huffman();
hf.insert(new Node(1));
hf.insert(new Node(2));
hf.insert(new Node(3));
hf.insert(new Node(4));
hf.insert(new Node(5));
hf.insert(new Node(6));
hf.run(list);
System.out.println("前序遍历");
hf.display(root);
System.out.println("\n中序遍历");
hf.drawTree(root);
}
}
执行结果:

后面,将写通过哈夫曼解析具体报文。
闲来无事写写-Huffman树的生成过程的更多相关文章
- NOI 2015 荷马史诗【BZOJ 4198】k叉Huffman树
抱歉因为NOIP集训,好长时间没再写题解了. NOI 2015也就只有这道题一看就能懂了-- 4198: [Noi2015]荷马史诗 Time Limit: 10 Sec Memory Limit: ...
- 【数据结构】Huffman树
参照书上写的Huffman树的代码 结构用的是线性存储的结构 不是二叉链表 里面要用到查找最小和第二小 理论上锦标赛法比较好 但是实现好麻烦啊 考虑到数据量不是很大 就直接用比较笨的先找最小 去掉最小 ...
- [数据结构与算法]哈夫曼(Huffman)树与哈夫曼编码
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- Huffman树与编码的简单实现
好久没写代码了,这个是一个朋友问的要C实现,由于不会C,就用JAVA写了个简单的.注释掉的代码属性按照原来朋友发的题里带的参数,发现没什么用就给注释掉了. package other; import ...
- Huffman树的编码译码
上个学期做的课程设计,关于Huffman树的编码译码. 要求: 输入Huffman树各个叶结点的字符和权值,建立Huffman树并执行编码操作 输入一行仅由01组成的电文字符串,根据建立的Huffma ...
- HUFFMAN 树
在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN) 树和哈夫曼编码.哈夫曼编码是哈夫曼树的一个应用.哈夫曼编码应用广泛,如 JPEG中就应用了哈夫曼编码. 首先介绍什么 ...
- Huffman树及其应用
哈夫曼树又称为最优二叉树,哈夫曼树的一个最主要的应用就是哈夫曼编码,本文通过简单的问题举例阐释哈夫曼编码的由来,并用哈夫曼树的方法构造哈夫曼编码,最终解决问题来更好的认识哈夫曼树的应用--哈夫曼编码. ...
- poj 3253 Fence Repair(模拟huffman树 + 优先队列)
题意:如果要切断一个长度为a的木条需要花费代价a, 问要切出要求的n个木条所需的最小代价. 思路:模拟huffman树,每次选取最小的两个数加入结果,再将这两个数的和加入队列. 注意priority_ ...
- Huffman树与最优二叉树续
OK,昨天我们对huffman数的基本知识,以及huffman树的创建做了一些简介,http://www.cnblogs.com/Frank-C/p/5017430.html 今天接着聊: huffm ...
随机推荐
- Javascript 获取窗口的大小和位置
在Javascript中可以使用OuterWidth,OuterHeight 获取浏览器的大小.用 innerWidth,innerHeight 来获取窗口的大小(除去浏览器边框部分).对于IE6 及 ...
- SQLServer .mdf和.ldf文件
.mdf:是数据库数据文件,存放一个数据库的数据信息. .ldf:是数据库日志文件,即日常对数据库的操作的记录如(增.删.改)的文件.
- Hibernate中为什么要重写equals方法和hashcode方法
1.*为什么要重写equals方法,首先我们来看一下equals源码: public boolean equals(Object anObject) { if (this == anObject) { ...
- ROS服务的理解
服务是节点之间通信的另一种方式,服务允许节点发起一个请求和接收一个响应. 打开终端在里面输入: roscore 查看当前的运行节点: rosnode list 返回结果: /rosout 查看当前的运 ...
- Java学习之利用集合发牌小练习
/* * 思路: * A:创建一个HashMap集合 * B:创建一个ArrayList集合 * C:创建花色数组和点数数组 * D:从0开始往HashMap里面存储编号,并存储对应的牌同时往Arra ...
- 框架开发(三)---smarty整合
一 smarty 是什么 Smarty是一个PHP的模板引擎.更明确来说,它可以帮助开发者更好地 分离程序逻辑和页面显示.最好的例子,是当程序员和模板设计师是不同的两个角色的情况,而且 大部分时候都不 ...
- poj 3592 Instantaneous Transference 缩点+最长路
题目链接 给一个n*m的图, 从0, 0这个点开始走,只能向右和向下. 图中有的格子有值, 求能获得的最大值. 其中有些格子可以传送到另外的格子, 有些格子不可以走. 将图中的每一个格子都看成一个点, ...
- codeforces 55D. Beautiful numbers 数位dp
题目链接 一个数, 他的所有位上的数都可以被这个数整除, 求出范围内满足条件的数的个数. dp[i][j][k], i表示第i位, j表示前几位的lcm是几, k表示这个数mod2520, 2520是 ...
- java 线程学习
转载:详见处http://lavasoft.blog.51cto.com/62575/27069 Java多线程编程总结 下面是Java线程系列博文的一个编目: Java线程:概念与原理 ...
- Java图形化界面设计——中间容器(Jpanel)
1. 将组件添加到JFrame中 方式之一: frame.getContentPane().add(childComponent) 用getContentPane()方法获得JFrame的内容面板, ...