哈夫曼编码测试

哈夫曼编码实践

实践内容

  • 设有字符集: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. 把实验结果截图上传到云班课

实践过程

  • 哈夫曼编码过程
  1. 对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。)

  2. 在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。

  3. 从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。

  4. 重复二和三两步,直到集合F中只有一棵二叉树为止。

  • 重要代码
    构造哈夫曼树
 while (nodes.size() > 1)
  {
      Collections.unmodifiableList(nodes);

      HuffmanNode left = nodes.get(nodes.size() - 2);
      left.setCode("0");  //左子树置为 0
      HuffmanNode right = nodes.get(nodes.size() - 1);
      right.setCode("1");  //右子树置为 1
      HuffmanNode parent = new HuffmanNode(null, left.getLength() + right.getLength());
      parent.setLeft(left);
      parent.setRight(right);
      nodes.remove(left);
      nodes.remove(right);
      nodes.add(parent);
  }

计算字母出现次数

char[] chars = new char[a];
    int[] times = new int[a];
    Iterator<Character> pl2 = counter.keySet().iterator();

    for (int i=0;i<=a;i++ )
    {
        if (pl2.hasNext())
        {
            chars[i] = pl2.next();
            times[i] = counter.get(chars[i]);
        }

    }
    List<HuffmanNode> list = new ArrayList<HuffmanNode>();

    for(int i = 0;i<a;i++)
    {
        System.out.print(chars[i]+"出现次数为:"+times[i]+"   \n");
        list.add(new HuffmanNode(chars[i]+"",times[i]));
    }

对树的内容进行编码

 List<HuffmanNode> list = new ArrayList<HuffmanNode>();
  Queue<HuffmanNode> queue = new ArrayDeque<HuffmanNode>();

  if (root != null)
  {
      queue.offer(root);
      root.getLeft().setCode(root.getCode() + "0");
      root.getRight().setCode(root.getCode() + "1");
  }

  while (!queue.isEmpty())
  {
      list.add(queue.peek());
      HuffmanNode node = queue.poll();
      if (node.getLeft() != null)
      {
          node.getLeft().setCode(node.getCode() + "0");
      }
      if (node.getRight() != null)
      {
          node.getRight().setCode(node.getCode() + "1");
      }

      if (node.getLeft() != null)
      {
          queue.offer(node.getLeft());
      }

      if (node.getRight() != null)
      {
          queue.offer(node.getRight());
      }
  }

对源文件进行编解码操作,并分别输出结果

HuffmanTree huffmanTree = new HuffmanTree();
  HuffmanNode node = createTree(nodeList);
  List<HuffmanNode> inlist = new ArrayList<HuffmanNode>();
  inlist = huffmanTree.breadth(node);

  String[] name = new String[number.length];
  String[] code = new String[number.length];

  File file1 = new File("src\\Huffman编码文件.txt");
  File file2 = new File("src\\Huffman解码文件.txt");
  FileWriter fileWriter1 = new FileWriter(file1);
  FileWriter fileWriter2 = new FileWriter(file2);

运行结果截图



posted on 2019-11-24 23:05  20182313-刘尧  阅读(170)  评论(0编辑  收藏  举报