哈夫曼树贪心算法c语言,算法导论——贪心算法:哈夫曼编码(霍夫曼编码)...

package org.loda.greedy;

import org.junit.Test;

import org.loda.structure.MinQ;

/**

*

* @ClassName: HuffmanCoding

* @Description: 哈夫曼编码

* @author minjun

* @date 2015年5月21日 上午12:04:02

*

*/

public class HuffmanCoding {

@Test

public void huffmanCoding(){

String text="ABRACADABRA!";

MinQ minQ=getMinQFromText(text);

Node root=getRoot(minQ);

printTree(root,"");

}

/**

*

* @Title: printTree

* @Description: 打印哈夫曼编码后的字符编码键值对

* @param @param x

* @param @param str 设定文件

* @return void 返回类型

* @throws

*/

private void printTree(Node x,String str) {

if(x.left==null&&x.right==null){

System.out.println("字符"+x.c+"\t——>编译码\t"+str);

return;

}

printTree(x.left,str+"0");

printTree(x.right,str+"1");

}

/**

*

* @Title: getRoot

* @Description: 构造哈夫曼树,并返回根节点

* @param @param minQ

* @param @return 设定文件

* @return Node 返回类型

* @throws

*/

private Node getRoot(MinQ minQ) {

//保证本次迭代前队列至少有两个元素,不然两次poll取出元素会报错

while(minQ.size()>1){

//选出当前最优解(即选出目前最小的两个节点,为其组合父亲节点,以便使得优先队列的元素不断组合成一棵二叉树)

Node x=minQ.poll();

Node y=minQ.poll();

//创建两个最小节点的父节点

Node node=new Node(x.freq+y.freq,'\0');

//将父节点与两个子节点组合

node.left=x;

node.right=y;

//将组合完成的父节点添加到哈弗曼树中

minQ.offer(node);

}

//取出哈夫曼树的根节点

return minQ.poll();

}

/**

*

* @Title: getMinQFromText

* @Description: 统计文本串中字符出现频率(次数),并以出现频率小到到排序(添加到优先队列)

* @param @param text

* @param @return 设定文件

* @return MinQ 返回类型

* @throws

*/

private MinQ getMinQFromText(String text) {

MinQ minQ=new MinQ();

int R=256;

Node[] nodes=new Node[R];

for(int i=0;i

if(nodes[text.charAt(i)]!=null){

nodes[text.charAt(i)].freq++;

}else{

nodes[text.charAt(i)]=new Node(1,text.charAt(i));

}

}

for(Node node:nodes){

if(node!=null){

minQ.offer(node);

}

}

return minQ;

}

class Node implements Comparable{

//访问频率

int freq;

//字母

char c;

//左右节点

Node left;

Node right;

public Node(int freq, char c) {

super();

this.freq = freq;

this.c = c;

}

@Override

public int compareTo(Node o) {

return this.freq-o.freq;

}

@Override

public String toString() {

return "Node [freq=" + freq + ", c=" + c + "]";

}

}

}

输出内容为:

字符A——>编译码0

字符D——>编译码100

字符!——>编译码1010

字符C——>编译码1011

字符R——>编译码110

字符B——>编译码111

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值