霍夫曼编码原理 C#版本
来源:互联网 发布:淘宝店铺怎么推广好 编辑:程序博客网 时间:2024/06/05 04:54
霍夫曼编码原理
在数据通信时,可以用0,1码的不同排列来表示字符。例如给定一段报文CAST CAST SAT AT A TASA,在报文中出现的字符集合是{C,A,S,T},各个字符出现的频度是{2,7,4,5}。若给每个字符一个等长的二进制表示,例如 C:00 A:01 S:10 T:11,则所发的报文将是00011011 00011011 100111 0111 01 11011001,共计(2+7+5+4)*2=36个码。若按字符出现的频度不同给予不同长度的编码,出现频度较大的字符采用为数较少的编码,出现频度较小的字符采用位书较多的编码,可以是报文的码数降到最小,这就是所谓的最小冗余编码问题。霍夫曼编码就能实现这种最小冗余编码。上例中按字符出现的频度进行编码,A:0 T:10 S:110C:111,则最终的报文只有35个码,节省了传输中使用的单元。因而霍夫曼编码是一种被广泛应用而且非常有效的数据压缩技术。
二.编码实现
一般情况下,霍夫曼编码的工作主要分为三步。
第一步是准备工作,对于需要编码的字符(一般存在于文件里)进行扫描,统计每个字符出现的频次,得到一个整数数组。
第二步根据这个频次数组构造一棵霍夫曼树,这步是霍夫曼编码的核心内容。
第三步,再次扫描一遍待编码的字符,对每个字符,在霍夫曼树里搜索该字符,得到它的编码。
这里通过C#软件实现,便于可视化的界面及操作方便性
// 学习小结 吴新强于2013年3月20日16:58:11 桂电 2507
//
//
//
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
namespace HuffmanCoding
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public struct Node//定义节点结构
{
public int weight; //定义权重
public int parent, lchild, rchild;//定义父亲,孩子
};
public struct Min//定义最小两位数结构
{
public int s1;
public int s2;
};
Node[] HTN = new Node[500];
Min Getmin(int n) //寻找最小的两位权值
{
int min1, min2, i;
Min code; //定义结构体Min
code.s1 = 1;
code.s2 = 1;
min1 = 256;
min2 = 256;
for (i = 0; i < n; i++)//寻找最小值
{
if (HTN[i].weight <= min1 && HTN[i].parent == 0)
{
min1 = HTN[i].weight;
code.s1 = i;
}
}
for (i = 0; i <= n; i++)//寻找次最小值
{
if (HTN[i].weight <= min2 && i != code.s1 && HTN[i].parent == 0)
{
min2 = HTN[i].weight;
code.s2 = i;
}
}
return code;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void richTextBox2_TextChanged(object sender, EventArgs e)
{
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)//编码响应
{
int length;//统计输入的字符个数
int Num = 0;//统计输入字符的种类
int i, j, k, m, start, c, f;
Min min;
int[] weight = new int[256];//用于统计每次字符出现的次数
int[] ind = new int[256];//用于统计i对应的字符
int[] wei = new int[256];//用于统计每个字符权重
string Input = richTextBox1.Text.Trim();//输入的编码字符存到Input数组中
string code = "";
if (richTextBox1.Text == "") MessageBox.Show("请输入编码字符!");
else
{
length = richTextBox1.Text.Length;
for (i = 0; i < length; i++)
weight[Input[i]]++; //统计每个字符出现的次数即权重
for (i = 0; i < 256; i++)
{
if (weight[i] != 0) //若个数不为0,将这个字符存入ind数组中,
{
ind[Num] = i; //Ind存放字符代码
wei[Num++] = weight[i];//相应的权重存放在weight数组中,记录个数输入的字符有num种
}
}
m = 2 * Num - 1;
for (i = 0; i < Num; i++)//初始化
{
HTN[i].weight = wei[i];
HTN[i].parent = 0;
HTN[i].lchild = 0;
HTN[i].rchild = 0;
}
for (; i < m; i++)
{
HTN[i].weight = 0;
HTN[i].parent = 0;
HTN[i].lchild = 0;
HTN[i].rchild = 0;
}
for (i = Num; i < m; i++)//建树
{
min = Getmin(i - 1); //找出最小的两位数
HTN[min.s1].parent = i;
HTN[min.s2].parent = i;
HTN[i].lchild = min.s1;
HTN[i].rchild = min.s2;
HTN[i].weight = HTN[min.s1].weight + HTN[min.s2].weight;
}
string[] HC = new string[Num];
char[] cd = new char[Num + 5];
for (i = 0; i < Num; i++)//对每个字符进行编码
{
start = Num + 5;
for (c = i, f = HTN[i].parent; f != 0; c = f, f = HTN[f].parent)
{
if (HTN[f].lchild == c) cd[--start] = '0';
else cd[--start] = '1';
}
for (j = start; j < Num + 5; j++)
HC[i] += cd[j];
}
for (i = 0; i < length; i++)//将输入字符编程码
{
k = 0;
int flag = 0;
for (j = 0; j < Num && flag == 0; j++)
{
if (ind[j] == Input[i])//寻找该字符对应的编码
{
k = j;
flag = 1;
}
}
code += HC[k].ToString();
}
richTextBox2.Text = code;//最终编码输出至richTextBox2中
for (i = 0; i < Num; i++)//将每个字符编码输出至listbox中
{
this.listBox1.Items.Add(Convert.ToString(Convert.ToChar(ind[i])) + ": " + HC[i]);
}
}
}
private void button2_Click(object sender, EventArgs e)//重新输入响应
{
richTextBox1.Text = "";
richTextBox2.Text = "";
this.listBox1.Items.Clear();
}
private void button3_Click(object sender, EventArgs e)//退出响应
{
this.Close();
}
}
}
实验截图:
- 霍夫曼编码原理 C#版本
- C#编码规范的几个版本
- 霍夫曼树和霍夫曼编码原理
- 编码原理
- 编码原理
- c# 编码
- C#编码 .
- Huffman Code(霍夫曼编码)原理及实例
- js版本的文本文件文件保存编码自动检测功能实现与检测原理
- 字符编码_Base64编码原理
- base64编码c++版本
- SICP_Python版本:Hufuman编码
- UTF8编码原理
- 音频编码原理
- MPEG4编码原理
- jsp,java编码原理
- Base64编码 原理
- 【转】JPEG编码原理
- 服务器应用--双缓冲队列
- linux-suse安装
- myeclipse 10.7.1下载地址
- Eclipse下Grails坏境搭建
- PE格式详解 输入表信息 (上)
- 霍夫曼编码原理 C#版本
- oracle 表分区
- STM8学习笔记之杂记(1.推挽输出与开漏输出的区别)
- linux 的date命令及系统时间设置
- 下拉框设置默认值
- View和Control的区别(如何在对话框上使用CView类)
- VC使用ado
- spring 管理N多个hibernate文件 的简便方法
- 用Java编写你自己的简单HTTP服务器