繁体   English   中英

霍夫曼编码-通往叶之路

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM