我已经组装了我的霍夫曼树,但现在我需要显示指定字母的路径。路径需要显示为1和0,其中1是右子,0是子。如果从根到达叶子是右子,右子,左子,路径将是110。
我能够打印每片叶子,但我无法弄清楚每条叶子的路径。我试图在我的代码中使用preOrder遍历方法。
import java.util.*;
import java.io。*;
公共课作业5 {
public static int nItems;
public static Node[] queueArray;
public static String path = "";
public static void main(String[] args) throws Exception{
int A = 0;
int B = 0;
int C = 0;
int D = 0;
int E = 0;
int F = 0;
int G = 0;
String fileName = "null";
if(args.length > 0){ //checks for arguments, if any exists it assigns first one to be the file name
fileName = args[0];
}
FileReader file = new FileReader(fileName);
BufferedReader reader = new BufferedReader(file);
String line = reader.readLine();
StringBuilder fileToString = new StringBuilder();
while(line != null){
fileToString.append(line);
line = reader.readLine();
}
fileToString.toString();
reader.close();
System.out.println(fileToString);
System.out.println("\n\n");
char[] letters = new char[fileToString.length()];
for(int i = 0; i < fileToString.length(); i++)
letters[i] = (fileToString.charAt(i));
for(int i = 0; i < letters.length; i++)
System.out.print(letters[i] + " ");
for(int i = 0; i < letters.length; i++){
if(letters[i] == 'A')
A++;
else if(letters[i] == 'B')
B++;
else if(letters[i] == 'C')
C++;
else if(letters[i] == 'D')
D++;
else if(letters[i] == 'E')
E++;
else if(letters[i] == 'F')
F++;
else if(letters[i] == 'G')
G++;
else{}
}
System.out.println("\n\nLetter frequencies are as follows:\nA= " + A + "\nB= " + B + "\nC= " + C + "\nD= " + D + "\nE= " + E + "\nF= " + F + "\nG= " + G);
Node node1 = new Node(A, 'A');
Node node2 = new Node(B, 'B');
Node node3 = new Node(C, 'C');
Node node4 = new Node(D, 'D');
Node node5 = new Node(E, 'E');
Node node6 = new Node(F, 'F');
Node node7 = new Node(G, 'G');
priorityQueue pq = new priorityQueue(13);
pq.insert(node1);
pq.insert(node2);
pq.insert(node3);
pq.insert(node4);
pq.insert(node5);
pq.insert(node6);
pq.insert(node7);
while(nItems>1)
pq.insert(pq.remove());
pq.displayTree();
pq.preOrder(queueArray[0], path);
}
public static class Node{
public int iData;
public char cData;
public Node leftChild;
public Node rightChild;
public Node(int freq, char lett){
iData = freq;
cData = lett;
leftChild = null;
rightChild = null;
}
}
public static class priorityQueue{
public int maxSize;
public priorityQueue(int size){
maxSize = size;
queueArray = new Node[maxSize];
nItems = 0;
}
public void insert(Node newLink){
int j;
if(nItems==0)
queueArray[nItems++]=newLink;
else{
for(j=nItems-1; j>=0; j--){
if(newLink.iData > queueArray[j].iData)
queueArray[j+1] = queueArray[j];
else
break;
}
queueArray[j+1] = newLink;
nItems++;
}
}
public void preOrder(Node localRoot, String code){
path = path + code;
if(localRoot != null){
if(localRoot.cData != ' '){
System.out.print(localRoot.cData + path + "\t");
path = "";
}
preOrder(localRoot.leftChild, "0");
preOrder(localRoot.rightChild, "1");
}
}
public Node remove(){
int freqs;
freqs = queueArray[nItems-1].iData + queueArray[nItems-2].iData;
Node newNode = new Node(freqs, ' ');
if(queueArray[nItems-1].iData < queueArray[nItems-2].iData){
newNode.leftChild = queueArray[nItems-1];
newNode.rightChild = queueArray[nItems-2];
}
else{
newNode.rightChild = queueArray[nItems-1];
newNode.leftChild = queueArray[nItems-2];
}
nItems-=2;
return newNode;
}
public void displayQueue(){
for(int i = 0; i<nItems; i++)
System.out.print(queueArray[i].cData + ", " + queueArray[i].iData + " | ");
}
public void displayTree(){
Node newNode = queueArray[0];
Queue<Node> currentLevel = new LinkedList<Node>();
Queue<Node> nextLevel = new LinkedList<Node>();
currentLevel.add(newNode);
while (!currentLevel.isEmpty()) {
Iterator<Node> iter = currentLevel.iterator();
while (iter.hasNext()) {
Node currentNode = iter.next();
if (currentNode.leftChild != null) {
nextLevel.add(currentNode.leftChild);
}
if (currentNode.rightChild != null) {
nextLevel.add(currentNode.rightChild);
}
System.out.print(currentNode.cData + " " + currentNode.iData + "\t");
}
System.out.println();
currentLevel = nextLevel;
nextLevel = new LinkedList<Node>();
}
}
}
}
答案 0 :(得分:0)
节点是否已知包含指定的字母或您是否必须先获取它?
假设您知道特定节点。我通常会在您的Node类中添加Node parent;
字段。在那之后,跟随父节点直到你到达根并且记录你到达那里的路径是非常简单的。
以下是一个如何完成的简单示例:
private String getPathTo(Node node) {
String path = "";
Node parent = node.getParent();
while(parent != null) {
if(parent.getLeft().getData().compareTo(node.getData()) == 0) path = "0" + path;
if(parent.getRight().getData().compareTo(node.getData()) == 0) path = "1" + path;
node = parent;
parent = node.getParent();
}
return path;
}
编辑: 我的密钥是String。只是为了方便起见。
private Node searchNode(Node root, String key) {
Node result = null;
LinkedList<Node> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
Node node = queue.poll();
if(node.getData().compareTo(key) == 0) { result = node; }
if(node.getLeft() != null) queue.add(node.getLeft());
if(node.getRight() != null) queue.add(node.getRight());
}
return result;
}
此方法假设密钥是唯一的。