(java哈夫曼树)用链式结构对字符串的读取,并编码,从而实现编译跟反编译.
思路:
1.获取文本的数据的时候,用一个容器来存放出现的字符跟频率,这里用了hashmap
2.把函数里面的数据赋值给相应链表的节点,然后用链表的排序,每次都把数据拿出来,赋值给一个新的节点,再放回去,实现了最后建树
3.递归遍历树,给树的节点赋值哈夫曼编码,每次都遍历到叶节点,而返回上一层的时候,需要记住把哈夫曼编码删除最后一位,实现返回上一层
4.编译跟反编译,就是遍历搜索树,因为我们自己输入的哈夫曼编码可能不在我们的树里,所以,只用输入文本.
5.改进了上面的代码,我们可以利用输入的01字符串,实现解码(通过遍历哈夫曼树)
建立链表
class ListNode
{
HuffmanNode data;
ListNode next;
ListNode()
{
this.data = null;
this.next = null;
}
ListNode(HuffmanNode hnode)
{
this.data = hnode;
this.next = null;
}
HuffmanNode getData()
{
return data;
}
}
哈夫曼节点
class HuffmanNode implements Comparable <HuffmanNode>
{
char thechar;
float weight;
int height;
HuffmanNode left;
HuffmanNode right;
StringBuilder huffmanCode;
HuffmanNode()
{
this.thechar = '\0';
this.weight = 0.0f;
this.height = 0;
this.left = null;
this.right = null;
this.huffmanCode = null;
}
HuffmanNode(char achar, float weight)
{
this.thechar = achar;
this.weight = weight;
this.height = 0;
this.left = null;
this.right = null;
this.huffmanCode = null;
}
public void setWeight(float weight) {
this.weight = weight;
}
void setHeight(int height)
{
this.height = height;
}
float getWeight()
{
return this.weight;
}
int getHeight()
{
return this.height;
}
void setLeftChild(HuffmanNode node)
{
this.left = node;
}
void setRightChild(HuffmanNode node)
{
this.right = node;
}
HuffmanNode getLeftChild()
{
return this.left;
}
HuffmanNode getRightChild()
{
return this.right;
}
char getChar()
{
return thechar;
}
String getHuffmanCode()
{
if (this.huffmanCode == null)
return "";
else
return this.huffmanCode.toString();
}
void setHuffmanCode(StringBuilder code)
{
this.huffmanCode = new StringBuilder(code);
}
public int compareTo(HuffmanNode node)
{
int val = 1;
if (this.getWeight() > node.getWeight())
return val;
else if (this.getWeight() < node.getWeight())
val = -1;
else
{
if (this.getChar()!='\0'){
if (this.getChar()>this.getChar())
return val;
else if (this.getChar() < node.getChar())
val = -1;
}
}
return val;
}
@Override
public String toString() {
return "HuffmanNode{" +
"thechar=" + thechar +
", weight=" + weight +
", left=" + left +
", right=" + right +
", huffmanCode=" + huffmanCode +
'}';
}
}
存放哈夫曼编码的链表
public class HuffmanList
{
ListNode head;
int len;
HuffmanList()
{
head = new ListNode();
len = 0;
}
void addNode(HuffmanNode hnode)
{
ListNode lnode = new ListNode(hnode);
lnode.next = head.next;
head.next = lnode;
len++;
}
HuffmanNode getFirstNode()
{
HuffmanNode p = head.next.getData();
head.next = head.next.next;
len--;
return p;
}
int getlen()
{
return len;
}
void output(HuffmanList list){
ListNode node=list.head.next;
while (node!=null){
System.out.println(node.getData().toString());
node=node.next;
}
}
}
哈夫曼树(主要方法都在这里面)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.util.*;
public class HuffmanTree {
HuffmanList HList=new HuffmanList();
HuffmanList addHlist(Map<Character, Float> txtMap){
for(Object key:txtMap.keySet()){
HList.addNode(new HuffmanNode((char)key, txtMap.get(key)));
}
return HList;
}
HuffmanList sortedHlist(HuffmanList HList){
int len=HList.getlen();
for (int i=0;i<len;i++){
ListNode tmp=HList.head;
while (tmp!=null&&tmp.next!=null&&tmp.next.next!=null){
if (tmp.next.getData().compareTo(tmp.next.next.getData())>0){
swap(tmp,tmp.next);
}
tmp=tmp.next;
}
}
return HList;
}
private void swap(ListNode tmp, ListNode next) {
tmp.next=next.next;
next.next=tmp.next.next;
tmp.next.next=next;
}
public void conTree(HuffmanList HList){
while (HList.getlen()>1){
sortedHlist(HList);
HuffmanNode parent=new HuffmanNode();
HuffmanNode lnode=HList.getFirstNode();
HuffmanNode rnode=HList.getFirstNode();
parent.setLeftChild(lnode);
parent.setRightChild(rnode);
parent.setWeight(lnode.getWeight()+rnode.getWeight());
HList.addNode(parent);
}
}
public void setCode(HuffmanNode root,String s){
StringBuilder sb=new StringBuilder();
if (root.getLeftChild()==null&&root.getRightChild()==null){
root.setHuffmanCode(sb.append(s));
return;
}
setCode(root.getLeftChild(),s+"0");
setCode(root.getRightChild(),s+"1");
}
public void outNode(HuffmanNode root){
if(root.getLeftChild()==null&&root.getRightChild()==null){
System.out.println(root.getChar()+" "+root.getWeight()+" "+root.getHuffmanCode());
return;
}
HuffmanNode left=root.getLeftChild();
if (root.getLeftChild()!=null){
outNode(left);
}
HuffmanNode right=root.getRightChild();
if (root.getRightChild()!=null){
outNode(right);
}
}
public void decoding(StringBuilder sb, HuffmanNode root, String str){
char thechar;
for (int i=0;i<str.length();i++){
thechar=str.charAt(i);
searchChar(sb,root,thechar);
}
}
public void searchChar(StringBuilder sb, HuffmanNode root, char thechar){
if (root==null){
return;
}
if (root.getChar()==thechar){
sb.append(root.huffmanCode);
System.out.print(root.getHuffmanCode());
}
searchChar(sb,root.getLeftChild(),thechar);
searchChar(sb,root.getRightChild(),thechar);
}
public void endecoding(List<StringBuilder> list, HuffmanNode root){
StringBuilder sb;
int i=0;
while (list.size()>0){
sb=list.remove(i);
searchCode(list,root,sb);
}
}
public void searchCode(List<StringBuilder> list, HuffmanNode root, StringBuilder sb){
if (root==null){
return;
}
if (root.huffmanCode==sb){
System.out.print(root.getChar());
}
searchCode(list,root.getLeftChild(),sb);
searchCode(list,root.getRightChild(),sb);
}
public void endecoding_1(String str,HuffmanNode root) {
int i=0;
HuffmanNode head=root;
StringBuilder sb=new StringBuilder();
while(i<str.length()) {
char c=str.charAt(i);
if(c=='0') {
root=root.left;
}
else if(c=='1') {
root=root.right;
}
if(root.getLeftChild()==null&&root.getRightChild()==null) {
sb.append(root.getChar());
root=head;
}
i++;
}
System.out.print(sb.toString());
}
public String getContext() {
StringBuilder sb=new StringBuilder();
String str=new String();
File txtFile=new File("D:\\download\\Decoding1\\src\\demo1.txt");
try {
FileReader read = new FileReader(txtFile);
int end;
while((end=read.read() )!=-1) {
sb.append((char)end);
}
str=sb.toString();
}catch(Exception e) {
System.out.print(e);
}
return str;
}
}
读文本
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class getContext {
Map<Character,Float> get() throws FileNotFoundException {
File txtFile=new File("D:\\download\\Decoding\\src\\Demo.txt");
Map<Character, Float> txtMap=new HashMap<Character, Float>();
try{
FileReader read = new FileReader(txtFile);
int end;
while((end=read.read() )!=-1){
if (txtMap.containsKey(((char)end))){
float weight=txtMap.get(((char)end));
weight+=1;
txtMap.put(((char)end),weight);
}else if (end>='a' && end<='z'){
txtMap.put(((char)end),1.0f);
}else if (end==' '){
txtMap.put(((char)end),1.0f);
}else if (end==','){
txtMap.put(((char)end),1.0f);
}else if (end=='.'){
txtMap.put(((char)end),1.0f);
}
}
int len=0;
for (float v:txtMap.values()){
len+=v;
}
for (Character key:txtMap.keySet()){
float weight=txtMap.get(key);
weight=weight/len;
txtMap.put(key,weight);
}
read.close();
} catch (IOException e) {
e.printStackTrace();
}
return txtMap;
}
}
main函数
public class Test {
public static void main(String[] args) throws FileNotFoundException {
Map<Character,Float> txtMap;
getContext g=new getContext();
txtMap=g.get();
HuffmanTree T=new HuffmanTree();
HuffmanList List=T.addHlist(txtMap);
T.conTree(List);
HuffmanNode root=List.getFirstNode();
T.setCode(root,"");
T.outNode(root);
Scanner in=new Scanner(System.in);
List<StringBuilder> list=new ArrayList<StringBuilder>();
StringBuilder sb=new StringBuilder();
System.out.println("please input the txt:");
String str=T.getContext();
T.decoding(sb,root,str);
}
}