闲来无事写写-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 ...
随机推荐
- BadUSB的防范研究
近期爆出的badUSB漏洞,通过将病毒植入固件,能够伪装成键盘等设备,直接控制电脑,业界还没有非常好的修复方法. 从安全产品的角度.对于这个问题的防范,有下面几点可能不成熟的想法 1.病毒伪装成键盘. ...
- Neo4j数据库简单
作为世界上先进的地图数据库,Neo4j如今,公司已成为许多互联网的首选.Neo4j它是基于java开源地图数据库开发,另外一个NoSQL数据库.Neo4j在保证对数据关系的良好刻画的同一时候.还支持传 ...
- Asp.net 获取服务器指定文件夹目录文件,并提供下载
string dirPath = HttpContext.Current.Server.MapPath("uploads/"); if (Directory.Exists(dirP ...
- jquery常用语句总结
一.jquery中text val html attr的使用区别 html和innerHTMl是一样的,可以获得和设置指定元素如<p>中的html标签和文本如:设置值: $("p ...
- 我的学习笔记之API-Guides翻译------AppComponent_Activites
10.26第一天开始:贵在坚持,边看遍整理 一个应用程序通常由多个Activity组成,它们之间是松耦合的关系.特别的,有一个Activity作为app的主Activity,当app首次启动时呈现给用 ...
- English - 英文写作中的最常见“十大句式”
英文写作中的最常见“十大句式” from 小木虫论坛 一.否定句 许多否定句不含not的否定结构.如果论文作者能正确使用他们,就会增加写作的闪光点,使文章显得生动活泼. 1.Instead of in ...
- iOS 常用第三方
MWPhotoBrowser 非常好用的图片浏览器 FDFullscreenPopGesture 用于全屏滑动切换视图 Aspects 用于快速AOP编程 AFNetworking iOS开发中最为火 ...
- Day 1: How to install jedi/codeintel plugin for sublime on Linux
Step 1, Install sublime3 Download sublime2/3 from http://www.sublimetext.com/ $tar -jxvf sublime_tex ...
- C 查找子字符串
自己用 C 写的一个查找子字符串的函数 int findstr(char *str,char *substr) //C实现 find{ if(NULL == str || NULL== substr) ...
- HTTP使用BASIC认证的原理及实现方法(还有NTLM方法,比较复杂)
一. BASIC认证概述 在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份证的方法,当一个客户端向HTTP服务 器进行数据请求时,如果客 ...