栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

哈夫曼树及其应用

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

哈夫曼树及其应用

一、实验目的:
掌握哈夫曼树的构造和应用,利用哈夫曼方法及其编/译码技术实现对传输信息编码/译码系统。

二、实验内容:
1、用静态链表存储哈夫曼树,根据结点字符及其权值构造哈夫曼树,并输出哈夫曼树中所有结点数据值和各字符的哈夫曼编码

哈夫曼树构造
    • 哈夫曼节点类
    • 哈夫曼树类
    • 测试
    • 应用

哈夫曼节点类
package HuffmanTree;

public class HuffmanNode {
    public int weight;
    public int flag;
    public HuffmanNode parent,lchild,rchild;
    public HuffmanNode(){
        this(0);
    }
    public HuffmanNode(int weight){
        this.weight = weight;
        flag = 0;
        parent = lchild = rchild = null;
    }
}

哈夫曼树类

包括哈夫曼树的构造函数、生成某一个字符的哈夫曼编码函数、输出一颗Huffman的结点数组和所有字符的哈夫曼编码

package HuffmanTree;

import java.util.HashMap;

public class HuffmanTree {
    //求哈夫曼编码
    public int[][] huffmanCoding(int[] W){
       int num = W.length;
        int m = 2 * num - 1;                    //哈夫曼节点数是2 * 叶节点数 - 1
        HuffmanNode[] HN = new HuffmanNode[m];
        int i;
        //构造n个有权值的根结点
        for (i = 0; i < num; i++) {
            HN[i] = new HuffmanNode(W[i]);
        }
        //构造哈夫曼树
        for (i = num;i < m; i++){
            HuffmanNode min1 = selectMin(HN,i - 1);
            min1.flag = 1;
            HuffmanNode min2 = selectMin(HN,i - 1);
            min2.flag = 1;
            HN[i] = new HuffmanNode();
            min1.parent = HN[i];
            min2.parent = HN[i];
            HN[i].lchild = min1;
            HN[i].rchild = min2;
            HN[i].weight = min1.weight + min2.weight;
          
        }
        //从叶子结点到根结点逆向求每个字符的哈夫曼编码
        int[][] HuffCode = new int[num][num];
        for (int j = 0; j < num; j++) {
            int start = num - 1;
            for (HuffmanNode c = HN[j],p = c.parent;p != null;c = p,p = p.parent){
                //左子树编码为0
                if (p.lchild.equals(c)){
                    HuffCode[j][start--] = 0;
                }else {
                    HuffCode[j][start--] = 1;
                }
            }
            //以-1作为编码开始的标识
            HuffCode[j][start] = -1;
        }
        return HuffCode;
    }

    private HuffmanNode selectMin(HuffmanNode[] HN,int end){
        HuffmanNode min = HN[end];
        for (int i = 0;i <= end; i++){
            HuffmanNode h = HN[i];
            if (min.weight > h.weight && h.flag == 0)
                min = h;
        }
        return min;
    }
}

测试
package HuffmanTree;

public class Test {
    public static void main(String[] args) {
        //int[] W = {6,30,8,9,15,24,4,12};
        int[] W = {5,29,7,8,14,23,3,11};
        HuffmanTree T = new HuffmanTree();
        int[][] huffmanCoding = T.huffmanCoding(W);
        System.out.println("哈夫曼编码为:");
        for (int i = 0;i 
应用 

2、[问题描述](设计性实验)
哈夫曼树很易求出给定字符集及其概率(或频度)分布的最优前缀码。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。该技术一般可将数据文件压缩掉20%至90%,其压缩效率取决于被压缩文件的特征。
请自行设计实现一个将文本压缩为Huffman编码序列、再将压缩的Huffman编码序列解压缩成原文本功能的哈夫曼码的编码/译码系统。并实现以下文本的压缩和解压缩:“this program is my favorite”。

[测试数据]
某文本的字符集为26个英文字母及空格字符,其出现频度如下表所示:

对节点类进行改进

package TextZip;

import HuffmanTree.HuffmanNode;

public class HuffmanNode_Zip extends HuffmanNode {
    public Object name;
    public String huffmanCode;
    public HuffmanNode_Zip(){
    }
    public HuffmanNode_Zip(Object name,int weight){
        this.name = name;
        this.weight = weight;
        flag = 0;
        parent = lchild = rchild = null;
    }
}

注:此代码仅为demo,不建议拷贝,运行尚不能满足所有测试
对应应用的哈夫曼树及哈夫曼编码
算法思路:

  1. 先将输入文本的不同字符记录,根据不同字符的数目来创建对应数目的节点,之后构造哈夫曼树及哈夫曼编码。同时因为哈夫曼编码的唯一性,所以通过Hashmap来存储不同字符对应的编码(用于压缩),以及不同编码对应的字符(用于解压缩)

特殊函数展示:

//判断target元素是否在arr数组里面
Arrays.asList(arr).contains(target);
package TextZip;

import HuffmanTree.HuffmanTree;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class HuffmanTree_Zip extends HuffmanTree {
    private String zip_Coding = "";
    private String unzip_Coding = "";
    private HashMap unzip_CodingMap;
    private HashMap zip_CodingMap;

    public int[][] huffmanCoding(String str){

        String[] chars = getChars(str);
        int num = chars.length;
        int m = 2 * num - 1;
        HuffmanNode_Zip[] HN = new HuffmanNode_Zip[m];
        int i;
        //构造n个有名字、有权值的根结点
        for ( i = 0; i < num; i++) {
            switch(chars[i]){
                case " ":
                    HN[i] = new HuffmanNode_Zip(chars[i],186);
                    break;
                case "a":
                    HN[i] = new HuffmanNode_Zip(chars[i],64);
                    break;
                case "b":
                    HN[i] = new HuffmanNode_Zip(chars[i],13);
                    break;
                case "c":
                    HN[i] = new HuffmanNode_Zip(chars[i],22);
                    break;
                case "d":
                    HN[i] = new HuffmanNode_Zip(chars[i],32);
                    break;
                case "e":
                    HN[i] = new HuffmanNode_Zip(chars[i],103);
                    break;
                case "f":
                    HN[i] = new HuffmanNode_Zip(chars[i],21);
                    break;
                case "g":
                    HN[i] = new HuffmanNode_Zip(chars[i],15);
                    break;
                case "h":
                    HN[i] = new HuffmanNode_Zip(chars[i],47);
                    break;
                case "i":
                    HN[i] = new HuffmanNode_Zip(chars[i],57);
                    break;
                case "j":
                    HN[i] = new HuffmanNode_Zip(chars[i],1);
                    break;
                case "k":
                    HN[i] = new HuffmanNode_Zip(chars[i],5);
                    break;
                case "l":
                    HN[i] = new HuffmanNode_Zip(chars[i],32);
                    break;
                case "m":
                    HN[i] = new HuffmanNode_Zip(chars[i],20);
                    break;
                case "n":
                    HN[i] = new HuffmanNode_Zip(chars[i],57);
                    break;
                case "o":
                    HN[i] = new HuffmanNode_Zip(chars[i],63);
                    break;
                case "p":
                    HN[i] = new HuffmanNode_Zip(chars[i],15);
                    break;
                case "q":
                    HN[i] = new HuffmanNode_Zip(chars[i],1);
                    break;
                case "r":
                    HN[i] = new HuffmanNode_Zip(chars[i],48);
                    break;
                case "s":
                    HN[i] = new HuffmanNode_Zip(chars[i],51);
                    break;
                case "t":
                    HN[i] = new HuffmanNode_Zip(chars[i],80);
                    break;
                case "u":
                    HN[i] = new HuffmanNode_Zip(chars[i],23);
                    break;
                case "v":
                    HN[i] = new HuffmanNode_Zip(chars[i],8);
                    break;
                case "w":
                    HN[i] = new HuffmanNode_Zip(chars[i],18);
                    break;
                case "x":
                    HN[i] = new HuffmanNode_Zip(chars[i],1);
                    break;
                case "y":
                    HN[i] = new HuffmanNode_Zip(chars[i],16);
                    break;
                case "z":
                    HN[i] = new HuffmanNode_Zip(chars[i],1);
                    break;
            }
        }
        //构造哈夫曼树
        for (i = num;i h.weight && h.flag == 0)
                min = h;
        }
        return min;
    }

    public boolean useList(char[] arr,char target){
        return Arrays.asList(arr).contains(target);
    }
    //用集合的元素唯一性,来将所有不重复的字符记录下来
    private String[] getChars(String str){
        int index = 0;
        String[] chars = new String[str.length()];
        for (int i=0;i hashMap = new HashMap();
        for (int i=0;i hashMap = new HashMap();
        for (int i=0;i keys = hashMap_zip.keySet();
        for (int i=0;i keys = hashMap.keySet();
        for (String key : keys){
            System.out.println(key+"="+hashMap.get(key));
        }
        System.out.println("原文本为:"+str);
        String zip_coding = huffmanTree_zip.zip_Coding(str);
        String unzip_coding = huffmanTree_zip.unzip_Coding(zip_coding);
        System.out.println("加密为:");
        System.out.print(zip_coding);
        System.out.println();
        System.out.println("解密为:");
        System.out.print(unzip_coding);
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/648294.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号