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

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

你可能感兴趣的:(Huffman)