• 大小: 11.01 KB
    文件类型: .rar
    金币: 2
    下载: 0 次
    发布日期: 2024-07-28
  • 语言: 其他
  • 标签:

资源简介

使用哈夫曼算法实现的文件压缩(源代码+实现报告)

资源截图

代码片段和文件信息

#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct HuffNode
{
long long weight;
int parent lchild rchild;
};
struct HuffTree
{
HuffNode *buffer;
int leafnum;  // buffer的长度为2*leafnum - 1
};
struct BitBuffer
{
    int buffer count;
};

int InitBitBuffer( BitBuffer &B ) // 初始化一个位流缓冲区
{
    B.buffer = B.count = 0;
    return 1;
}
bool AppendBit( BitBuffer &B int bit)  // 向位流缓冲区中追加一位
{
if (bit==1) B.buffer = (B.buffer << 1) | 1;//如果bit为1buffer左移一位并与1位或,也就是最右面添1
    else B.buffer = B.buffer << 1;
    B.count++;
    return B.count>=8;  // 如果已填充满了8位,返回真
}
int countfre(FILE *fplong long *&cal)//进行文件字节频率统计
{
int ch;
while((ch=fgetc(fp))!=EOF)
cal[ch]++;
return 1;
}
//创建哈夫曼树 
int CreateHuffTree(HuffTree &T int leafnum long long weight[])
{
// 初始化哈夫曼树的空间
T.buffer = new HuffNode[2*leafnum-1];
T.leafnum = leafnum;
for (int i=0; i {
    T.buffer[i].weight = weight[i];
    T.buffer[i].parent = -1;
    T.buffer[i].lchild = -1;
    T.buffer[i].rchild = -1;
}
for (int i=0; i {// 选出两棵根结点权值最小的树
int m1=-1 m2=-1;
for (int j=0; j {// 先判断buffer[j]是否是根,如果不是根,则跳过
    if (T.buffer[j].parent==-1)
    {
        if (m1==-1 || T.buffer[j].weight         {//m2为次小的,m1为最小的下标 
            m2 = m1; m1 = j;
        }
        else if (m2==-1 || T.buffer[j].weight             m2 = j;
    }
}
// 创建一个新的根结点,将选出的两棵树分别挂在新根结点的左右子上
T.buffer[m1].parent = i+leafnum;
T.buffer[m2].parent = i+leafnum;
T.buffer[i+leafnum].parent = -1;
if(m1 {
T.buffer[i+leafnum].lchild = m1;
T.buffer[i+leafnum].rchild = m2;
}
else
{
T.buffer[i+leafnum].lchild = m2;
T.buffer[i+leafnum].rchild = m1;
}
T.buffer[i+leafnum].weight = T.buffer[m1].weight + T.buffer[m2].weight;
}
return 1;
}
//使用哈夫曼编码对文件进行重编码,并输出新文件
int coding(HuffTree T FILE *fp FILE *outf)
{
//把哈夫曼树写入文件
for(int i=0;i<511;i++)
{
int byte=T.buffer[i].parent-256;
fputc(byteoutf);
}
//在第512个字节的位置加入空字节
fputc(0outf);
//根据静态三叉链构成的哈夫曼树的结构,前buffer[0到leafnum-1]这leafnum个数据中存有叶子结点,根据读到的数据调用对应位置的buffer[]即可 
int ch;
BitBuffer B;//位流 
InitBitBuffer(B);
stack temp;//用来存放每个字节对应的哈夫曼编码 
while((ch=fgetc(fp))!=EOF)
{//读取fp文件中的字节 
while(T.buffer[ch].parent!=-1)
{
if(ch==T.buffer[T.buffer[ch].parent].lchild) temp.push(0);
else if(ch==T.buffer[T.buffer[ch].parent].rchild) temp.push(1);
ch=T.buffer[ch].parent;
}
while(!temp.empty())
{//位流转换为字节流并输出到文件中 
if(AppendBit(Btemp.top())==1)
{
fputc(B.bufferoutf);
InitBitBuffer(B);
}
temp.pop();
}
}
//处理buffer没到8位的情况
for(int i=B.count;i<8;i++)
B.buffer = B.buffer << 1;//最后追加0
fputc(B.bufferoutf);
//把B.count放入文件开始预留的位置
fseek(outf511L0);
fputc(B.

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----

     文件       7469  2007-01-11 19:12  哈夫曼压缩算法.cpp

     文件      50176  2007-12-08 09:44  哈夫曼压缩算法.doc

----------- ---------  ---------- -----  ----

                57645                    2


评论

共有 条评论