日撸java 三百行 (day 17 )哈夫曼编码 (02建树)

日撸java 三百行 (day 17 )哈夫曼编码 (02建树),第1张

昨天已经把基本准备工作做完了,今天主要是建立哈夫曼树。

  • 第一步:创建叶子节点,将字符与对应的权值赋值给叶子节点
  • 第二步:通过两个for循环建立哈夫曼树。外层循环 i 代表非叶子节点,内层循环 j 依次遍历当前已经存在的节点,两个内层循环可以选出其中权值最小的两个节点(这里需要一个标记数组,为了避免重复选择同一个),将两个权值最小的节点相加得到其父节点,最后连接其父子关系。具体过程如下图:

 

 

 

 

 

/**
    *********************
    * Construct the tree.
    * 
    * @return HuffmanNode 
    *              The Root
    *********************
    */

    public HuffmanNode constructTree() {
        // Step 1. Allocate space.
        nodes = new HuffmanNode[alphabetLength * 2 - 1];
        boolean[] tempProcessed = new boolean[alphabetLength * 2 - 1];
        // Step 2. Initialize leaves.
        for (int i = 0; i < alphabetLength; ++i) {
            nodes[i] = new HuffmanNode(alphabet[i], charCounts[i], null, null, null);
        }//of for i

        // Step 3. Construct the tree.
        int templeft, tempright, tempMiniMal;
        for (int i = alphabetLength; i < alphabetLength * 2 - 1; ++i) {
            // Step 3.1 Select the first minimal as the left child.
            templeft = -1;
            tempMiniMal = Integer.MAX_VALUE;
            for (int j = 0; j < i; ++j) {
                if (tempProcessed[j]) {
                    continue;
                }//of if
                if (charCounts[j] < tempMiniMal) {
                    tempMiniMal = charCounts[j];
                    templeft = j;
                }// Of if
            }// Of for j
            tempProcessed[templeft] = true;

            // Step 3.2 Select the second minimal as the right child.
            tempright = -1;
            tempMiniMal = Integer.MAX_VALUE;
            for (int j = 0; j < i; j++) {
                if (tempProcessed[j]) {
                    continue;
                }// Of if
                if (charCounts[j] < tempMiniMal) {
                    tempMiniMal = charCounts[j];
                    tempright = j;
                }// Of if
            }// Of for j
            tempProcessed[tempright] = true;
            System.out.println("select " + templeft + " " + "and " + tempright);

            // Step 3.3 Construct the new node.
            charCounts[i] = charCounts[templeft] + charCounts[tempright];
            nodes[i] = new HuffmanNode('*', charCounts[i], nodes[templeft], nodes[tempright], null);

            // Step 3.4 Link with children.
            nodes[templeft].parent = nodes[i];
            nodes[tempright].parent = nodes[i];
            System.out.println("The children of " + i + " are " + templeft + " and " + tempright);
        }// Of for i
        return nodes[nodes.length - 1];
    }// Of constructTree


    /**
     * ********************
     * Pre-order visit.
     * ********************
     */
    public void preOrderVisit(HuffmanNode paraNode) {
        System.out.print("(" + paraNode.character + ", " + paraNode.weight + ") ");
        if (paraNode.leftChild != null) {
            preOrderVisit(paraNode.leftChild);
        }// Of if
        if (paraNode.rightChild != null) {
            preOrderVisit(paraNode.rightChild);
        }// Of if
        return;
    }// Of preOrderVisit


    public static void main(String[] args) {
        MyHuffman tempHuffman = new MyHuffman("C:/Users/胡来的魔术师/Desktop/test.txt");
        tempHuffman.constructAlphabet();
        HuffmanNode tempNode = tempHuffman.constructTree();
        tempHuffman.preOrderVisit(tempNode);
    }//of main

}//of  MyHuffman 

用先序遍历来试一下:

 总结:确实今天开始写算法后,昨天还感觉很多的变量今天都能记住了,突然发现也没有想象中那么难,只要理清逻辑,一直就按部就班。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/726202.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存