资源简介
利用哈夫曼编码进行对已有文件进行重新编码可以大大提高减小文件大小,减少存储空间。但是,这要求在首先对一个现有文件进行编码行成新的文件,也就是压缩。在文件使用时,再对压缩文件进行解压缩,也就是译码,复原原有文件
代码片段和文件信息
// huffman.cpp : Defines the entry point for the console application.
//
#include “stdafx.h“
//哈夫曼编码压缩解压缩程序.cpp
#include
#include
#include
#include
struct head
{
unsigned char b; //记录字符在数组中的位置
long count; //字符出现频率(权值)
long parentlchrch; //定义哈夫曼树指针变量
char bits[256]; //定义存储哈夫曼编码的数组
}
header[512]tmp;
/*压缩*/
void compress()
{
char filename[255]outputfile[255]buf[512];
unsigned char c;
long ijmnf;
long min1pt1flengthlength1length2;
double div;
FILE *ifp*ofp;
printf(“\t请您输入需要压缩的文件:“);
gets(filename);
ifp=fopen(filename“rb“);
if(ifp==NULL)
{
printf(“\n\t文件打开失败!\n\n“);
return;
}
printf(“\t请您输入压缩后的文件名:“);
gets(outputfile);
ofp=fopen(strcat(outputfile“.hub“)“wb“);
if(ofp==NULL)
{
printf(“\n\t压缩文件失败!\n\n“);
return;
}
flength=0;
while(!feof(ifp))
{
fread(&c11ifp);
header[c].count++; //字符重复出现频率+1
flength++; //字符出现原文件长度+1
}
flength--;
length1=flength; //原文件长度用作求压缩率的分母
header[c].count--;
for(i=0;i<512;i++)
{
if(header[i].count!=0) header[i].b=(unsigned char)i;
/*将每个哈夫曼码值及其对应的ASCII码存放在一维数组header[i]中,
且编码表中的下标和ASCII码满足顺序存放关系*/
else header[i].b=0;
header[i].parent=-1;header[i].lch=header[i].rch=-1; //对结点进行初始化
}
for(i=0;i<256;i++) //根据频率(权值)大小,对结点进行排序,选择较小的结点进树
{
for(j=i+1;j<256;j++)
{
if(header[i].count {
tmp=header[i];
header[i]=header[j];
header[j]=tmp;
}
}
}
for(i=0;i<256;i++) if(header[i].count==0) break;
n=i; //外部叶子结点数为n个时,内部结点数为n-1,整个哈夫曼树的需要的结点数为2*n-1.
m=2*n-1;
for(i=n;i {
min1=999999999; //预设的最大权值,即结点出现的最大次数
for(j=0;j {
if(header[j].parent!=-1) continue;
//parent!=-1说明该结点已存在哈夫曼树中,跳出循环重新选择新结点*/
if(min1>header[j].count)
{
pt1=j;
min1=header[j].count;
continue;
}
}
header[i].count=header[pt1].count;
header[pt1].parent=i; //依据parent域值(结点层数)确定树中结点之间的关系
header[i].lch=pt1; //计算左分支权值大小
min1=999999999;
for(j=0;j {
if(header[j].parent!=-1) continue;
if(min1>header[j].count)
{
pt1=j;
min1=header[j].count;
continue;
}
}
header[i].count+=header[pt1].count;
header[i].rch=pt1; //计算右分支权值大小
header[pt1].parent=i;
}
for(i=0;i {
f=i;
header[i].bits[0]=0; //根结点编码0
while(header[f].parent!=-1)
{
j=f;
f=header[f].parent;
if(header[f].lch==j) //置左分支编码0
{
j=strlen(header[i].bits);
memmove(header[i].bits+1header[i].bitsj+1);
//依次存储连接“0”“1”编码
header[i].bits[0]=‘0‘;
}
else //置右分支编码1
{
j=strlen(header[i].bits);
memmove(
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 4548 2010-01-11 23:03 huffman\huffman.dsp
文件 522 2010-01-11 23:03 huffman\huffman.dsw
文件 50176 2009-04-13 19:39 huffman\huffman.ncb
文件 248 2009-04-13 19:38 huffman\huffman.plg
文件 1214 2010-01-11 23:03 huffman\ReadMe.txt
文件 294 2010-01-11 23:03 huffman\StdAfx.cpp
文件 667 2010-01-11 23:03 huffman\StdAfx.h
文件 200749 2010-01-13 18:04 huffman\Debug\huffman.exe
文件 252500 2010-01-13 18:04 huffman\Debug\huffman.ilk
文件 186996 2010-01-11 23:04 huffman\Debug\huffman.pch
文件 549888 2010-01-13 18:04 huffman\Debug\huffman.pdb
文件 1600 2010-01-11 23:04 huffman\Debug\StdAfx.obj
文件 41984 2009-04-13 19:38 huffman\Debug\vc60.idb
文件 86016 2010-01-13 18:04 huffman\Debug\vc60.pdb
文件 20086 2010-01-13 18:04 huffman\Debug\huffman.obj
目录 0 2010-01-11 23:17 huffman\Debug
文件 103771 2010-01-12 20:01 huffman\11.hub
文件 9960 2010-01-12 21:02 huffman\huffman.cpp
文件 48640 2009-04-13 19:39 huffman\huffman.opt
目录 0 2010-01-12 10:28 huffman
----------- --------- ---------- ----- ----
1559859 20
- 上一篇:三国志游戏源代码C语言版本
- 下一篇:N皇后问题启发式算法
评论
共有 条评论