• Huffman树,Huffman编码的实现(C#)


    思路来自 《算法导论》
      1 /*
      2  * 
      3  * 1. 创建最小优先级队列
      4  * 2. 用最小优先级队列创建Huffman树
      5  * 3. 得到Huffman编码
      6  * 
      7  */
      8 
      9 using System;
     10 using System.Collections.Generic;
     11 using System.Collections;
     12 using System.Linq;
     13 using System.Text;
     14 using System.IO;
     15 
     16 namespace HuffmanTree
     17 {
     18 
     19     class Node : IComparable
     20     {
     21         public int data;
     22         public Node left;
     23         public Node right;
     24         public Node parent;
     25         public char character = '@';
     26         public string code = "";
     27         public Node() { }
     28         public Node(int data, Node left = null, Node right = null, char character = '@')
     29         {
     30             this.data = data;
     31             this.left = left;
     32             this.right = right;
     33             this.character = character;
     34         }
     35         public int CompareTo(object obj)
     36         {
     37             Node node = obj as Node;
     38             return this.data.CompareTo(node.data);
     39         }
     40     }
     41     /// <summary>
     42     /// 最小优先级队列
     43     /// 1. 取出最小元素,
     44     /// 2. 得到最小元素
     45     /// 3. 插入一个元素
     46     /// 4. 元素个数
     47     /// </summary>
     48     class MinPriorityQueue 
     49     {
     50         List<Node> list = new List<Node>();
     51 
     52         public void Insert(Node node)
     53         {
     54             list.Add(node);
     55             list.Sort(); // 此处可以改进(用线性插入法)
     56             
     57         }
     58 
     59         public Node ExtraceMin()
     60         {
     61             Node temp = list[0];
     62             list.RemoveAt(0);
     63             return temp;
     64         }
     65 
     66         public int Count // 属性:计数器
     67         {
     68             get { return list.Count; }
     69         }
     70     }
     71 
     72     /// <summary>
     73     /// 文件读取类
     74     /// </summary>
     75     class MyReader
     76     {
     77         string path;
     78         Dictionary<char, int> dict = new Dictionary<char, int>();
     79         public  MyReader(string path = "")
     80         {//初始化
     81             this.path = path;
     82             for (int i = 0; i < 26; i++)
     83             {
     84                 dict.Add((char)((int)'a'+i), 0);
     85             }
     86 
     87         }
     88         /// <summary>
     89         /// 设置 或 返回当前文件的路径
     90         /// </summary>
     91         public string Path
     92         {
     93             get { return this.path; }
     94             set { this.path = value; }
     95         }
     96 
     97         public Dictionary<char, int> Count()
     98         {
     99             try
    100             {
    101                 StreamReader sr = new StreamReader(this.path);
    102                 string line;
    103                 while ((line = sr.ReadLine()) != null)
    104                 {
    105 
    106                     foreach (char item in line)
    107                     {
    108                         if ((item >= 'a' && item <= 'z') || (item >= 'A' && item <= 'Z'))
    109                         {
    110                             char temp = item;
    111                             temp = char.ToLower(temp);
    112 
    113                             dict[temp]++;
    114                         }
    115                     }
    116                     
    117                 }
    118             }
    119             catch (System.Exception ex)
    120             {
    121                 Console.WriteLine(ex.Message);
    122             }
    123 
    124             return dict;
    125         }
    126 
    127 
    128     }
    129     class Program
    130     {
    131 
    132         static public Node BuildHuffmanTree(MinPriorityQueue queue)
    133         {
    134 
    135             while (queue.Count > 1)
    136             {
    137                 Node temp = new Node();
    138                 Node node1 = queue.ExtraceMin();
    139                 Node node2 = queue.ExtraceMin();
    140                 temp.data = node1.data + node2.data;
    141                 temp.left = node1;
    142                 temp.right = node2;
    143                 node1.parent = temp;
    144                 node2.parent = temp;
    145                 queue.Insert(temp);
    146             }
    147             return queue.ExtraceMin();
    148         }
    149 
    150 
    151         /// <summary>
    152         /// 通过遍历进行Hufman编码,并输出
    153         /// </summary>
    154         /// <param name="root"></param>
    155         static public void traverse(Node root)
    156         {
    157             if (root != null)
    158             {
    159                 if (root.character != '@')
    160                     Console.WriteLine("{1,8}{0,4}    {2}", root.character, root.data, root.code);
    161 
    162                 if (root.left != null)
    163                 {
    164                     root.left.code = root.left.parent.code + "0";
    165                     traverse(root.left);
    166                 }
    167                 if (root.right != null)
    168                 {
    169                     root.right.code = root.left.parent.code + "1";
    170                     traverse(root.right);
    171                 }
    172             }
    173         }
    174 
    175         static void Main(string[] args)
    176         {
    177             MinPriorityQueue queue = new MinPriorityQueue();
    178 
    179             MyReader mr = new MyReader();
    180             mr.Path = "LittlePrince.txt";
    181             Dictionary<char, int> dict = mr.Count();
    182             foreach (char item in dict.Keys)
    183             {
    184                 Node node = new Node(dict[item], character:item);
    185                 queue.Insert(node);
    186             }
    187             Node root = BuildHuffmanTree(queue);
    188 
    189             Console.WriteLine("    频率  字符  编码");
    190             traverse(root);
    191 
    192             Console.ReadKey();
    193         }
    194     }
    195 }
    
    
     
    《Little Prince》中的英文字符(大小写不区分)的Huffman编码:

  • 相关阅读:
    js,js中使用正则表达式
    web开发中文件下载
    EL表达式
    Servlet Filter
    压缩文件 乱码问题(转载)
    MFC CopyDirectory
    SaveFileDialog
    Create Window
    CDateTimeCtrl 设置时间
    键值表
  • 原文地址:https://www.cnblogs.com/wangshide/p/2476796.html
Copyright © 2020-2023  润新知