java huffman树的构造和huffman编码
2016-06-04 22:32
375 查看
以下片段实现了huffman树的构造,中序遍历,和huffman编码
import java.util.ArrayList; import algorithmDesign.TreeTraverse.Node; public class HuffmanTree { /*创建两个内部类表示结点和编码*/ class Node{ //表示huffman树结点 int weight; //weight表示权重 char data; //data表示权重 //parent,left,right分别指向父结点,左右孩子的在huffman树数组中的位置 int parent,left,right; public Node(){ /*空构造函数*/ } } class Code{ //存储huffman结点对应的huffman编码 int start; char []co; public Code(int n){ /*因为huffman编码是不等长的,编码结点的最大长度设置为huffman树结点数n, 编码保存在char型数组中,start表示编码在char数组中的有效起始位置*/ start=-1; co=new char ; } } public void HufmanTree(int n,int [] weight,char []ch, Node[] hufnode){ int i,j,mw1,mw2,node1,node2; for(i=0;i<2*n-1;i++){//初始化 hufnode[i]=new Node(); /*前n个结点为叶子结点*/ if(i<n){ hufnode[i].weight=weight[i]; hufnode[i].data=ch[i]; }else{ hufnode[i].weight=-1; hufnode[i].data='-'; } hufnode[i].parent=-1; hufnode[i].left=-1; hufnode[i].right=-1; } for(i=n;i<2*n-1;i++){ /*mw1,mw2用于保存最小权重的两个结点的值, * 初始时设置一个较大的数 node1,node2用于保存最小权重的两个结点的位置*/ mw1=mw2=10000; node1=-1; node2=-1; for(j=0;j<i;j++){ //找到权值最小的两个结点 if(hufnode[j].parent==-1){ if(hufnode[j].weight<mw1){ mw2=mw1;node2=node1; mw1=hufnode[j].weight;node1=j; }else if(hufnode[j].weight<mw2){ mw2=hufnode[j].weight;node2=j; } } } /*用node1和node2构造一颗新的二叉树,二叉树的根的权值为node1和node2的权值和*/ hufnode[i].weight=hufnode[node1].weight+hufnode[node2].weight; hufnode[i].data='+'; /*填充根的左右孩子指针,使其只向node1和node2*/ hufnode[i].left=node1; hufnode[i].right=node2; /*node1和node2的双亲为新构造的根*/ hufnode[node1].parent=i; hufnode[node2].parent=i; } } public static void inOrderTraverse(int h,Node[] hufnode){//中序遍历输出huffmanTree if(h!=-1){ if(hufnode[h].left!=-1){ inOrderTraverse(hufnode[h].left, hufnode); } System.out.print(hufnode[h].data+":"+hufnode[h].weight+", "); if(hufnode[h].right!=-1){ inOrderTraverse(hufnode[h].right, hufnode); } }else{ return; } } public void HufmanCode(int n, Node[] hufnode, Code[] hufcode){ int i,parent,child; //parent,child分别指向父亲和孩子结点 for(i=0;i<n;i++){ //计算每个结点的huffman编码 Code hc=new Code(n); //创建Code结点 hc.start=n-1; //start表示编码在char数组中的有效起始位置,从后向前存放编码值*/ child=i; parent=hufnode[i].parent; while(parent!=-1){ //没有到达根结点,则继续编码 if(hufnode[parent].left==child){ hc.co[hc.start--]='0'; //左孩子编码 }else{ hc.co[hc.start--]='1'; //右孩子编码 } child=parent; parent=hufnode[parent].parent; //向根进发 } hc.start++; hufcode[i]=hc; //获的一个编码 } } public static void main(String args[]){ int [] weight=new int[]{3,8,6,1,5}; int n=5; char [] ch =new char[]{'a','b','c','d','e'}; Node[] hufnode=new Node[2*n-1]; Code[] hufcode=new Code ; HuffmanTree hf=new HuffmanTree(); hf.HufmanTree(n, weight, ch, hufnode); //构造huffman树 inOrderTraverse(2*n-2,hufnode); //中序遍历输出huffman树 System.out.println(); hf.HufmanCode(n, hufnode, hufcode); //计算huffman编码 for(int i=0;i<hufcode.length;i++){ //输出huffman树中每个结点的编码 System.out.print(hufnode[i].data); for(int j=hufcode[i].start-1;j<n;j++){ System.out.print(hufcode[i].co[j]); } System.out.println(); } } }
相关文章推荐
- java Web高并发解决方案
- java 图的邻接矩阵表示,深度优先遍历,广度优先遍历
- Struts2-学习笔记系列(9)-OGNL类型转换和类型绑定
- SpringMVC细节
- java 图的邻接表存储,广度优先遍历
- Spring笔记(三)
- Elasticsearch Client(JAVA API) JAVA实例
- Struts2-学习笔记系列(8)-异常处理
- Struts2-学习笔记系列(7)-PreResultListener
- Struts2-学习笔记系列(7)-PreResultListener
- JAVA :Jpanel 控件 无法显示问题
- java : JSP页面上中文乱码问题的解决经验
- Struts2-学习笔记系列(6)-动态调用action
- Struts2-学习笔记系列(5)-配置action
- Java中的IO流API整理
- Struts2-学习笔记系列(4)-访问servlet api
- java常用工具类【2】
- Struts2-学习笔记系列(3)-返回视图
- Struts2-学习笔记系列(2)-常量配置和实现action
- java中如何将byte数组内容转换为字符串?