java huffman树的构造和huffman编码

以下片段实现了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[n];   
            }
        }

    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[n];

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

    }

}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值