C#实现Huffman编码和解码

关于Huffman概念,参见数据结构书

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; } } }

转载于:https://www.cnblogs.com/iwteih/archive/2010/01/18/1650388.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值