c#编写哈夫曼编码
假设用于通信的电子由字符集{a,b,c,d,e,f,g,h}中的字母构成,这8个字母在电文中出现的概率分别为{0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.10},为这8个字母设计哈夫曼编码。请各位帮个忙,这道题目如何用C#编写,谢谢!!
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; namespace StringCompresser { public class Huffman { //char and its bitarray public Dictionary<char, BitArray> HuffmanCode = null; //Huffman tree public Node[] HuffmanTree = null; //huffman tree node internal struct Node { internal char character; internal int weight; internal int parent; internal int lchild; internal int rchild; } public Huffman(char[] charArray, int[] weight) { if (weight == null || weight.Length == 0 || charArray == null || charArray.Length == 0 || weight.Length != charArray.Length) return; HuffmanCode = new Dictionary<char, BitArray>(); //build huffman tree int totalNodeNum = weight.Length * 2 - 1; HuffmanTree = new Node[totalNodeNum + 1]; //initialize the first weight.Length nodes with wight. //The 0 element is reserved for other purpose for(int i = 0; i < weight.Length; i++) { HuffmanTree[i + 1] = new Node { weight = weight[i], parent = 0, lchild = 0, rchild = 0, character= charArray[i] }; } for (int i = weight.Length + 1; i < HuffmanTree.Length; i++) { //select two min weight from huffmanTree.parent is 0 //This Algorithm only traverse array once #region selection int? min1 = null; int? min2 = null; int min1Pos = 0; int min2Pos = 0; for (int j = 1; j < i; j++) { if (HuffmanTree[j].parent == 0) { if (min1 == null) { min1 = HuffmanTree[j].weight; min1Pos = j; continue; } if (min2 == null) { if (HuffmanTree[j].weight < min1.Value) { min2 = min1; min2Pos = min1Pos; min1 = HuffmanTree[j].weight; min1Pos = j; } else { min2 = HuffmanTree[j].weight; min2Pos = j; } continue; } if(min1 != null && min2 != null) { if (HuffmanTree[j].weight < min1) { min2 = min1; min2Pos = min1Pos; min1 = HuffmanTree[j].weight; min1Pos = j; } else if (HuffmanTree[j].weight < min2) { min2 = HuffmanTree[j].weight; min2Pos = j; } } } } #endregion HuffmanTree[min1Pos].parent = HuffmanTree[min2Pos].parent = i; HuffmanTree[i].lchild = min1Pos; HuffmanTree[i].rchild = min2Pos; HuffmanTree[i].weight = min1.Value + min2.Value; } //Get huffman code int p = 0,c =0; List<bool> values = null; for (int i = 1; i <= weight.Length; i++) { values = new List<bool>(); //one points to _current node, one point to _parent node for (c = i, p = HuffmanTree[c].parent; p != 0; c = p, p = HuffmanTree[p].parent) { if (HuffmanTree[p].lchild == c)//0 { values.Add(false); } else//1 { values.Add(true); } } values.Reverse(); HuffmanCode.Add(charArray[i - 1], new BitArray(values.ToArray())); } } //Encode a string to bitarray public BitArray Encode(string input) { if (string.IsNullOrEmpty(input)) return null; List<bool> list = new List<bool>(); foreach (char ch in input) { BitArray ba = HuffmanCode[ch]; foreach (bool b in ba) { list.Add(b); } } return new BitArray(list.ToArray()); } //Decode a bitarray to a string public string Decode(BitArray bitArray) { if (bitArray == null) return null; string rtnString = string.Empty; int ic = HuffmanTree.Length - 1;//Root Node current = HuffmanTree[ic]; int i = 0; while (i <= bitArray.Length - 1) { while (current.lchild != 0 && current.rchild != 0) { current = bitArray[i++] ? HuffmanTree[current.rchild] : HuffmanTree[current.lchild]; } rtnString = string.Concat(rtnString, current.character); current = HuffmanTree[ic]; } return rtnString; } //Get char from a char bitarray private char GetCharacter(BitArray array) { int ic = HuffmanTree.Length - 1;//Root Node c = HuffmanTree[ic]; foreach (bool b in array) { if (b) { ic = c.rchild; } else { ic = c.lchild; } c = HuffmanTree[ic]; } return c.character; } } }可以参考一下这个例子