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编码:

原文地址:https://www.cnblogs.com/wangshide/p/2476796.html