用java实现曼彻斯特编码_java实现哈弗曼编码

本文介绍了如何使用Java实现哈弗曼编码。通过构建最优二叉树,根据最小带全路径确定哈弗曼编码。文章提供了一个TNode类用于表示树的节点,包括权值、左右子节点以及哈弗曼编码。接着在Tree类中构建最优树,从键盘读取权值,使用迭代器找出最小权值节点进行组合。最后,通过HuffmanCode类实现哈弗曼编码的生成和查看。测试结果显示了哈弗曼编码的生成过程。
摘要由CSDN通过智能技术生成

根据输入的各个叶节点的权值,构建一棵最优树,根据最小带全路径,确定由0,1组成的哈弗曼编码。

首先在一个封装类TNode中构建一棵树的元素,比如权值,左节点,右节点,同时在TNode类中构建了哈弗曼编码值,以及判断节点是否为叶子节点

package霍夫曼编码;/***

*@authorluckid

*@version2014_10_11

**/

/*** 定义Huffman编码的节点*/

public classTNode {/***

*@paramweight

*@paramleft

*@paramright*/

/*protected*/ int weight; //权值

TNode left=null; //左节点

TNode right=null; //右节点

String code=null; //霍夫曼编码/*** 构造一个赫夫曼编码节点的实例。设定左右子树和权值*/

public TNode(intweight,TNode left,TNode right){this.weight=weight;this.left=left;this.right=right;

}/***

*@author刘雁冰as

* @date 2015-02-08 1943

**/

public TNode(intweight){this.weight=weight;

}/*** 判断本节点是否为叶子节点

*@returnboolean 为叶子节点则返回true*/

public booleanisLeaf(){return (left==null&&right==null);

}/*** 返回本节点的权值

*@returnnt 本节点的权值*/

public intgetWeight(){returnweight;

}/*** 返回本节点的左孩子节点

*@returnTNode 左孩子节点*/

publicTNode getLeft(){returnleft;

}/*** 返回本节点的右孩子节点

*@returnTNode 右孩子节点*/

publicTNode getRight(){returnright;

}/*** 设置节点的赫夫曼编码

*@paramstr String 被设置的赫夫曼编码*/

public voidsetCode(String str){

code=str;

}/*** 得到节点的赫夫曼编码

*@returnString 被设置的赫夫曼编码*/

publicString getCode(){returncode;

}

}

在Tree类中,构建一棵最优树。首先从键盘读入权值,在这里用1,3,5,7作为测试数据,将读入的测试数据放在一个数组链表中。接着使用迭代器求出最小的叶子节点,然后递归构建一棵最优树,在建构最优树的时候,一次递归需要找出权值最小的叶子节点以及权值次小的叶子节点,两个节点构成一棵子最优树。循序渐进继续递归,直到数组链表中只剩下一个数据,作为整棵最优树的根节点。

测试数据构成的最优子树应该如下:

4e3160e43eb92a8678c4d02098f0b632.png

/*** 定义最优二叉树*/

/*protected*/ TNode root; //二叉树根节点

/*protected*/ ListleafList=new ArrayList(); //存储叶子节点的权值

/*protected*/ ListtempList=new LinkedList(); //临时队列,用于存放待组合的节点

/*protected*/TNode[]leafArr=null; //存放带权节点

/*** 键盘读取各个权值*/

public voidgetLeafWeight(){

Scanner sc=newScanner(System.in);

System.out.println("请输入各个叶节点的权值,按0为结束:");while(sc.hasNextInt()){int i=sc.nextInt();if(i==0)break;

leafList.add(newInteger(i));

}

sc=null;return;

}/*** 找出临时队列中权值最小的节点从队列中移出并返回

*@returnTNode 权值最小的节点*/

publicTNode min(){

Iteratoriter=tempList.iterator();

TNode minNode=iter.next();int min=minNode.getWeight(); //找到最小的节点

TNode tempNode;while(iter.hasNext()){

tempNode=iter.next();if(tempNode.getWeight()

min=tempNode.getWeight();

minNode=tempNode;

}

}

tempList.remove(minNode);//最小的节点移出临时队列//处理垃圾

iter=null;

tempNode=null;returnminNode;

}/*** 根据权值创建叶子节点并加入临时队列*/

public voidmakeLeafNode(){

leafArr=newTNode[leafList.size()];for(int i=0;i

TNode node=newTNode(leafList.get(i).intValue());

leafArr[i]=node;

tempList.add(node);

}

}/*** 根据权值构造最优的二叉树*/

public voidmakeBestTree(){

makeLeafNode();//根据权值创建叶子节点并加入临时队列

TNode minNode1=null;

TNode minNode2=null;

TNode node=null;while(tempList.size()!=1){ //构造最优树

minNode1=min();

minNode2=min();

node=new TNode(minNode1.getWeight()+minNode2.getWeight(),minNode1,minNode2);

tempList.add(node);

}

root=node;

}

构建好了最优树,就可以用HuffmanCode类拓展最优二叉树实现哈弗曼编码。在HuffmanCode类中递归调用huff()方法创建哈弗曼树结构,并且为每个叶子节点赋值,其中左子树赋值0,右子树赋值1

package霍夫曼编码;/***

*@author刘雁冰as

* @date 2015-02-08 1943

**/

/*** 拓展最优二叉树实现Huffman编码

* 赫夫曼编码类*/

public class HuffmanCode extendsTree{publicHuffmanCode(){

init();

}/*** 初始化节点值并构造最优二叉树*/

public voidinit(){super.getLeafWeight();super.makeBestTree();

}/*** 生成赫夫曼编码的递归函数

*

*@paramt TNode 当前遍历节点

*@params String 目前遍历至此的赫夫曼编码*/

/*protected*/public voidhuff(TNode t,String s){if(t.isLeaf()){

t.setCode(s);

}else{

huff(t.left,s+"0");

huff(t.right,s+"1");

}

}/*** 生成赫夫曼编码的外部调用函数*/

public voidmakeHuffmanCode(){

huff(root,"");

}/*** 查看所有的赫夫曼编码值*/

public voidviewHuffmanCode(){for(int i=0;i

System.out.println(leafArr[i].weight+":"+leafArr[i].getCode());

}

}

}

测试类:

package霍夫曼编码;public classApplication {/***

*@author刘雁冰as

* @date 2015-02-08 1943

**/

public static voidmain(String args[]){//TODO Auto-generated method stub

HuffmanCode hu=newHuffmanCode();

hu.makeHuffmanCode();

hu.viewHuffmanCode();

}

}

测试结果如下:

9603422b54f75f596a6660a0bac3ca47.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值