闲来无事写写-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 ...
随机推荐
- servlet生成随机验证码
package com.cgyue; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import jav ...
- Python操作Access数据库
我们在这篇文章中公分了五个步骤详细分析了Python操作Access数据库的相关方法,希望可以给又需要的朋友们带来一些帮助. AD: Python编 程语言的出现,带给开发人员非常大的好处.我们可以利 ...
- SQL学习之去重复查询
下面是一张表的数据
- 2014.8.20break,continue,字符串,数字和日期
(一)break与continue break——彻底终断循环 continue——中断本次循环,继续下次循环 break举例: //求100以内所有质数 ; i <= ; i++) { ;// ...
- iOS开发通过代码方式使用AutoLayout (NSLayoutConstraint + Masonry)
iOS开发通过代码方式使用AutoLayout (NSLayoutConstraint + Masonry) 随着iPhone6/6+设备的上市,如何让手头上的APP适配多种机型多种屏幕尺寸变得尤为迫 ...
- vs vsvim viemu vax 备忘
使用gt和gT往返标签 gd:到达光标所在处函数或者变量的定义处. *:读取光标处的字符串,并且移动光标到它再次出现的地方. #:和上面的类似,但是是往反方向寻找. /text:从当前光标处开始搜索字 ...
- js浮点数精度问题
大多数语言在处理浮点数的时候都会遇到精度问题,但是在JS里似乎特别严重,来看一个例子 alert(45.6*13); 结果居然是592.800000000001,当然加法之类的也会有这个问题 那这是j ...
- eclipse注解快捷键
Search 功能:全局文件内容搜索快捷键: Ctrl + H -------------------------------------------------------------------- ...
- 四轴飞行器1.1 Matlab 姿态显示
四轴飞行器1.1 Matlab 姿态显示 开始做四轴了,一步一步来,东西实在很多,比较杂.先做matlab上位机,主要用来做数据分析,等板子到了可以写飞控的程序了,从底层一层一层开始写..希望能好好的 ...
- linux下如何查看系统和内核版本
1. 查看内核版本命令: 1) [root@q1test01 ~]# cat /proc/version Linux version 2.6.9-22.ELsmp (bhcompile@cro ...