[英]Huffman Coding - Get Path to Leaf
我已经组装好了霍夫曼树,但是现在我需要显示指定字母的路径。 路径需要显示为1和0,其中1是右孩子,0是左孩子。 如果要从根到叶是右子,右子,左子,则路径将为110。
我能够打印每片叶子,但是我无法弄清楚通往每片叶子的路径。 我正在尝试在代码中使用preOrder遍历方法。
import java.util.*;
导入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>();
}
}
}
}
是否知道包含指定字母的节点,还是必须先获取它?
假设您知道特定的节点。 我通常会添加一个Node parent;
字段添加到您的Node类。 之后,跟随父节点非常简单,直到到达根节点并只记录到达该节点的路径。
这是一个简单的示例,该如何完成:
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;
}
编辑:我的钥匙在这里是一个字符串。 只是为了方便。
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;
}
此方法假定键是唯一的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.