Java 哈夫曼树编码

Java 哈夫曼树编码,java,traversal,huffman-code,Java,Traversal,Huffman Code,我之前问过的哈夫曼树还有一个问题!代码如下: package huffman; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; import java.util.PriorityQueue; import java.util.Scanner; public class Huffman { public ArrayList<Frequency

我之前问过的哈夫曼树还有一个问题!代码如下:

package huffman;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Huffman {

    public ArrayList<Frequency> fileReader(String file)
    {
        ArrayList<Frequency> al = new ArrayList<Frequency>();
        Scanner s;
        try {

            s = new Scanner(new FileReader(file)).useDelimiter("");
            while (s.hasNext())
            {
                boolean found = false;
                int i = 0;
                String temp = s.next();
                while(!found)
                {


                    if(al.size() == i && !found)
                    {
                        found = true;
                        al.add(new Frequency(temp, 1));
                    }
                    else if(temp.equals(al.get(i).getString()))
                    {
                        int tempNum = al.get(i).getFreq() + 1;
                        al.get(i).setFreq(tempNum);
                        found = true;
                    }
                    i++;

                }



            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return al;
    }
    public Frequency buildTree(ArrayList<Frequency> al)
    {
        Frequency r = al.get(1);
        PriorityQueue<Frequency> pq = new PriorityQueue<Frequency>();
        for(int i = 0; i < al.size(); i++)
        {
            pq.add(al.get(i));          
        }
        /*while(pq.size() > 0)
        {
            System.out.println(pq.remove().getString());
        }*/

        for(int i = 0; i < al.size() - 1; i++)
        {   
           Frequency p = pq.remove(); 
           Frequency q = pq.remove();
           int temp = p.getFreq() + q.getFreq();
           r = new Frequency(null, temp);
           r.left = p; 
           r.right = q;
           pq.add(r);  // put in the correct place in the priority queue
        }
        pq.remove(); // leave the priority queue empty
        return(r); // this is the root of the tree built

    }

    public void inOrder(Frequency top)
    {
        if(top == null)
        {
            return;
        }
        else
        {
            inOrder(top.left);
            System.out.print(top.getString() +", ");
            inOrder(top.right);
            return;
        }
    }
    public void printFreq(ArrayList<Frequency> al)
    {
        for(int i = 0; i < al.size(); i++)
        {
            System.out.println(al.get(i).getString() + "; " + al.get(i).getFreq());
        }
    }

}
packagehuffman;
导入java.io.FileNotFoundException;
导入java.io.FileReader;
导入java.util.ArrayList;
导入java.util.PriorityQueue;
导入java.util.Scanner;
公共级哈夫曼{
公共ArrayList文件读取器(字符串文件)
{
ArrayList al=新的ArrayList();
扫描器;
试一试{
s=新扫描仪(新文件读取器(文件)).useDelimiter(“”);
而(s.hasNext())
{
布尔值=false;
int i=0;
字符串temp=s.next();
而(!found)
{
如果(al.size()==i&&!找到)
{
发现=真;
新增(新频率(温度1));
}
else if(temp.equals(al.get(i).getString())
{
int tempNum=al.get(i.getFreq()+1;
al.get(i).setFreq(tempNum);
发现=真;
}
i++;
}
}
}catch(filenotfounde异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回al;
}
公共频率构建树(ArrayList al)
{
频率r=al.get(1);
PriorityQueue pq=新的PriorityQueue();
对于(int i=0;i0)
{
System.out.println(pq.remove().getString());
}*/
对于(int i=0;i
现在需要做的是,我需要创建一个方法,在树中搜索特定字符的二进制代码(011001等)。最好的方法是什么?我想也许我会在这棵树上做一个普通的搜索,就好像它是一棵AVL树,如果它更大,就向右搜索;如果它更小,就向左搜索

但是,因为节点不使用整数、双精度等,而只使用包含字符串的对象或null来表示其不是叶,而是根。另一种选择是按顺序运行以找到我正在寻找的叶子,但同时如何确定我是向右走了这么多次还是向左走了这么多次以获得角色

package huffman;

public class Frequency implements Comparable  {
    private String s;
    private int n;
    public Frequency left;
    public Frequency right;

    Frequency(String s, int n)
    {
        this.s = s;
        this.n = n;
    }
    public String getString()
    {
        return s;
    }
    public int getFreq()
    {
        return n;
    }
    public void setFreq(int n)
    {
        this.n = n;
    }
    @Override
    public int compareTo(Object arg0) {
        Frequency other = (Frequency)arg0;

        return n < other.n ? -1 : (n == other.n ? 0 : 1);
    }
}
packagehuffman;
公共类频率实现可比性{
私有字符串;
私人int n;
公共频率左;
公共频率权;
频率(字符串s,整数n)
{
这个.s=s;
这个,n=n;
}
公共字符串getString()
{
返回s;
}
公共int getFreq()
{
返回n;
}
公共无效设置频率(整数n)
{
这个,n=n;
}
@凌驾
公共整数比较对象(对象arg0){
频率其他=(频率)arg0;
返回n
我要做的是找到二进制代码,以实际获取每个字符。因此,如果我试图对
aabbbcccc
进行编码,我将如何创建一个包含二进制代码的字符串,左移为0,右移为1


让我困惑的是,你无法确定什么东西在哪里,因为树显然是不平衡的,而且无法确定角色是在你所在位置的右边还是左边。因此,您必须搜索整个树,但如果您找到的节点不是您要查找的节点,则必须返回到另一个根,才能找到其他叶。

请记住,如果您有1001,则永远不会有10010或10011。因此,您的基本方法如下所示(在伪代码中):

我并没有阅读你的程序来找出如何集成它,但简而言之,这是哈夫曼编码的一个关键元素

尝试类似的方法-您正在尝试查找令牌。因此,如果您想查找“10010”的字符串,您需要进行搜索(根,“10010”)


遍历哈夫曼树节点以获得类似{'a':“1001”、'b':“10001”}等的映射。您可以使用此映射获取特定字符的二进制代码

package huffman;

public class Frequency implements Comparable  {
    private String s;
    private int n;
    public Frequency left;
    public Frequency right;

    Frequency(String s, int n)
    {
        this.s = s;
        this.n = n;
    }
    public String getString()
    {
        return s;
    }
    public int getFreq()
    {
        return n;
    }
    public void setFreq(int n)
    {
        this.n = n;
    }
    @Override
    public int compareTo(Object arg0) {
        Frequency other = (Frequency)arg0;

        return n < other.n ? -1 : (n == other.n ? 0 : 1);
    }
}
如果需要反向操作,只需将其作为状态机处理即可:

state = huffman_root
for each bit
    if (state.type == 'leaf')
        output(state.data);
        state = huffman_root
    state = state.leaves[bit]

老实说,我没有检查你的代码。这应该是非常明显的如何处理花式树。

当我尝试使用哈夫曼编码树时,我考虑了两种选择

选项1:使用基于指针的二叉树。我对其中的大部分进行了编码,然后觉得,要从叶子上追踪树以找到编码,我需要父指针。另一方面,正如本文中提到的,您对树进行搜索,而这并不是一个直接找到编码的解决方案。基于指针的树的缺点是,对于我认为太多的树中的每个节点,我必须有3个指针。遵循指针的代码很简单,但比选项2中的代码更复杂

选项2:使用基于数组的树来报告
state = huffman_root
for each bit
    if (state.type == 'leaf')
        output(state.data);
        state = huffman_root
    state = state.leaves[bit]