以前質問したハフマン木には別の問題があります。コードは次のとおりです。
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());
}
}
}
ここで行う必要があるのは、ツリーを検索して特定の文字のバイナリ コード (011001 など) を見つけるメソッドを作成する必要があることです。これを行う最善の方法は何ですか?AVLツリーが大きい場合は右に、小さい場合は左に行くように、ツリーを通常の検索を行うのではないかと思いました。
ただし、ノードはints doubleなどを使用せず、文字列またはnullとして文字を含むオブジェクトのみを使用して、リーフではなくルートのみを示すためです。もう1つのオプションは、探している葉を見つけるために順番通りに実行することですが、同時に、文字を取得するために何度も右に行ったのか、何度も左に行ったのかをどのように判断するのでしょうか.
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);
}
}
私がやろうとしているのは、実際に各文字に到達するためのバイナリ コードを見つけることです。したがって、エンコードしようとしている場合aabbbcccc
、左に行くと 0、右に行くと 1 のバイナリ コードを保持する文字列を作成する方法を教えてください。
私が混乱しているのは、ツリーが明らかにバランスが取れておらず、キャラクターが自分のいる場所の右か左かを判断できないため、何かがどこにあるかを判断できないためです. したがって、ツリー全体を検索する必要がありますが、探しているものではないノードに到達した場合は、別のルートに戻って他のリーフに到達する必要があります。