转码思路:每次遍历一次树取出字符
测试的时候发现少了三个字符,原来是传错串了...
节点
public class HTNode {
char data;
int weight;
public HTNode parent;
HTNode lchild;
HTNode rchild;
boolean flag;
public HTNode()
{
parent=null;
lchild=null;
rchild=null;
}
public double getweight()
{
return weight;
}
}
哈夫曼建树及转换为编码,编码转字符串。
public class Huffman {
final int MaxN=100;
int[] w;
public static int n=0;
String str;
public static String s;
static int wn;
static HTNode[] ht;
static String[] hcd;
public Huffman()
{
ht=new HTNode[MaxN];
hcd=new String[MaxN];
w=new int[MaxN];
s="";
}
public void init(int wn,int[] w,String str)
{
this.wn=wn;
for(int index=0;index<wn;index++)
{
this.w[index]=w[index];
}
this.str=str;
}
public void createHT()
{
Comparator<HTNode> priComparator=new Comparator<HTNode>() {
@Override
public int compare(HTNode o1, HTNode o2) {
// TODO Auto-generated method stub
return (int) (o1.getweight()-o2.getweight());
}
};
PriorityQueue<HTNode> que=new PriorityQueue<>(100,priComparator);
for(int index=0;index<wn;index++)
{
ht[index]=new HTNode();
ht[index].parent=null;
ht[index].data=str.charAt(index);
ht[index].weight=w[index];
que.offer(ht[index]);
}
//create new node
for(int index=wn;index<2*wn-1;index++)
{
HTNode p1=que.poll();
HTNode p2=que.poll();
ht[index]=new HTNode();
p1.parent=ht[index];
p2.parent=ht[index];
ht[index].weight=p1.weight+p2.weight;
ht[index].lchild=p1;
p1.flag=true;
ht[index].rchild=p2;
p2.flag=false;
que.offer(ht[index]);//into the queue
}
}
public static HTNode Code(String str)
{
HTNode p = null;
for(int index=0;index<wn;index++)
{
hcd[index]="";
p=ht[index];
while(p.parent!=null)
{
if(p.flag)
{
hcd[index]+='0';
}
else
{
hcd[index]+='1';
}
p=p.parent;
}
hcd[index]=reverse(hcd[index]);
}
for(int index=0;index<str.length();index++)
{
char a=str.charAt(index);
for(int j=0;j<wn;j++)
{
if(a==ht[j].data)
{
s+=hcd[j];
}
}
}
System.out.println("HuffCode:"+s);
return p;//the root
}
public static String reverse(String s)
{
String t="";
for(int index1=s.length()-1;index1>=0;index1--)
{
t+=s.charAt(index1);
}
return t;
}
public static void showCode()
{
for(int index=0;index<wn;index++)
{
System.out.println(ht[index].data+" "+hcd[index]);
}
}
public static void transformtoString(HTNode root)
{
while(n<s.length())
{
String(root);
}
}
public static void String(HTNode root)
{
if(root.lchild==null)
{
if(root.data==46||root.data==44||root.data==32||(root.data<=122&&root.data>=97))
{
System.out.print(root.data);
}
return;
}
else
{
if(s.charAt(n)=='0')
{
n++;
String(root.lchild);
}
else if(s.charAt(n)=='1')
{
n++;
String(root.rchild);
}
}
}
}
测试类
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="abdrecufghijklmnopqstvwzxy ,.";//最后三个没有是因为传错初始化串了
char[] a=s.toCharArray();
String word="";
int wn=0;
System.out.println("alen:"+a.length);
String str="recursion is one of the most fundamental concepts in computer science and a key programming technique that,similarly to iteration,allows computations to be carried out repeatedly.it accomplishes this by employing methods that invoke themselves,where the central idea consists of designing a solution to a problem by relying on solutions to smaller instances of the same problem. most importantly,recursion is a powerful problem-solving approach that enables programmers to develop concise,intuitive,and elegant algorithms.";
//String str="aaa bdfghijklm,.nopqstvwzxy recu";
for(int index=0;index<a.length;index++)
{
for(int j=0;j<str.length();j++)
{
if(a[index]==str.charAt(j))
{
word+=a[index];
wn++;
break;
}
}
}
System.out.println("wn"+wn);
int[] w=new int[wn];//weight
System.out.println("word: "+word);
char[] newword=word.toCharArray();
for(int index=0;index<newword.length;index++)
{
for(int j=0;j<str.length();j++)
{
if(newword[index]==str.charAt(j))
{
w[index]++;
}
}
}
Huffman tree=new Huffman();
tree.str=word;
tree.wn=wn;
tree.init(tree.wn, w, tree.str);
tree.createHT();
HTNode root=tree.Code(str);
tree.showCode();
tree.transformtoString(root);
}
}