您的位置:首页 > 编程语言 > Java开发

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();
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: