20192312吴欣欣 哈夫曼编码实践 实验报告

20192312 2020-2021-1 实验七 《查找与排序》实验报告

课程:《程序设计与数据结构》
班级: 1923
姓名: 吴欣欣
学号:20192312
实验教师:王志强
实验日期:2020年12月10日
必修/选修: 必修

1.实验内容

设有字符集:S={a,b,c,d,e,f,g,h,i,j,k,l,m,n.o.p.q,r,s,t,u,v,w,x,y,z}。
给定一个包含26个英文字母的文件,统计每个字符出现的概率,根据计算的概率构造一颗哈夫曼树。
并完成对英文文件的编码和解码。
要求:
(1)准备一个包含26个英文字母的英文文件(可以不包含标点符号等),统计各个字符的概率
(2)构造哈夫曼树
(3)对英文文件进行编码,输出一个编码后的文件
(4)对编码文件进行解码,输出一个解码后的文件
(5)撰写博客记录实验的设计和实现过程,并将源代码传到码云
(6)把实验结果截图上传到云班课

2.实验过程及结果

1.编写结点类,除叶子结点,既字母外,其他结点权重为子结点权重之和。同时实现对节点的编码。

package week14;

public class HaffNode<T>{
    char data;
    int weight;
    HaffNode father,leftChild,rightChild;
    public HaffNode(char s){
        this.data=s;
        weight=0;
        father=null;
        leftChild=null;
        rightChild=null;
    }
    public HaffNode(HaffNode a,HaffNode b){
        this.data=' ';
        weight=a.weight+b.weight;
        father=null;
        leftChild=a;
        rightChild=b;
        a.father=this;
        b.father=this;
    }
    public String code(HaffNode root){//逆向编码
        String a="";
        if(father!=null){
            if(this==father.leftChild)a+="0"+father.code(root);
            else a+="1"+father.code(root);
        }
        return a;
    }
    public String recode(HaffNode root){
        String a=code(root);
        String b="";
        for(int i=a.length()-1;i>=0;i--){
            b+=a.charAt(i);
        }
        return b;
    }
}


2.编写哈夫曼树,排序后连接权重最小的两结点并插入新结点再排序。

package week14;
import java.util.Arrays;

public class HaffTree <T>{
    HaffNode root;
    public HaffTree(){
        root=null;
    }
    public HaffTree(HaffNode [] node){
        while(node.length>1){
            node=sort(node);
            HaffNode current=new HaffNode(node[0],node[1]);
            node[1]=current;
            node= Arrays.copyOfRange(node,1,node.length);
        }
        root=node[0];
    }
    public HaffNode[] sort(HaffNode[] node){
        for(int gap=node.length/2;gap>0;gap/=2){
            for(int i=gap;i<node.length;i++){
                int j=i;
                while (j-gap>=0&&node[j].weight<node[j-gap].weight){
                    swap(node,j,j-gap);
                    j-=gap;
                }
            }
        }
        return node;
    }
    public void swap(HaffNode [] node,int a,int b){
        HaffNode temp;
        temp=node[a];
        node[a]=node[b];
        node[b]=temp;
    }
    public String decode(String s){//解码
        String str="";
        int i=0;
        HaffNode current=root;
        while(i<s.length()) {
            while (current.leftChild != null) {
                if (s.charAt(i)=='0') current = current.leftChild;
                else current = current.rightChild;
                i++;
            }
            str+=current.data;
            current=root;
        }
        return str;
    }
}


3.测试代码

package week14;


import java.io.*;
import java.util.Arrays;

public class test {
    public static void main(String[] args) throws IOException {
        String s = "",s1="";
        char a = 'a';
        HaffNode[] node = new HaffNode[26];
        for (int i = 0; i < 26; i++) {
            node[i] = new HaffNode(a);
            a++;
        }
        File file= new File("C:\\Users\\86139\\Desktop", "file1.txt");  //创建文件对象
        File file1=new File("C:\\Users\\86139\\Desktop","file2.txt");
        File file2=new File("C:\\Users\\86139\\Desktop","file3.txt");
        if(!file1.exists()) { file1.createNewFile(); }
        if(!file2.exists()) { file2.createNewFile(); }
        FileReader fr1 = new FileReader(file);
        FileReader fr2 = new FileReader(file1);
        s=Read(fr1);
        fr1.close();
        for (int i = 0; i < s.length(); i++) {
            int num = s.charAt(i) - 'a';
            node[num].weight++;
        }
        HaffNode[] node1 = Arrays.copyOf(node, node.length);
        FileWriter fw1=new FileWriter(file1);
        FileWriter fw2=new FileWriter(file2);
        String code = "";
        HaffTree tree = new HaffTree(node1);
        for (int i = 0; i < s.length(); i++) {
            int num = s.charAt(i) - 'a';
            code += node[num].recode(tree.root);
        }
        fw1.write(code);
        fw1.close();
        s=Read(fr2);
        fr2.close();
        fw2.write(tree.decode(s));
        fw2.close();
    }
    public static String Read(FileReader fr) throws IOException {
        String s="";
        char[] data = new char[26];
        int length =0;
        while ((length = fr.read(data)) > 0) {
            s+= new String(data, 0, length);
        }
        return s;
    }
}




3.心得体会

巩固了File,以及FileReader等知识,同时又重新回顾了排序的相关内容。

posted @ 2020-12-13 21:00  20192312吴欣欣  阅读(454)  评论(0编辑  收藏  举报