霍夫曼编码+详细源代码及注释
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
return 0; }
Hufuman.h 头文件
#include<stdio.h> #include<stdlib.h> #include<string.h> #include"iostream"
/*1,定义霍夫曼树的节点 */ //---------------------------------------------struct node{
//----------------------初始化数组
for(int i=0;i<256;i++){
queue[i].name=i;
//初始化字符
queue[i].number=0; //初始化字符出现的次数
}
//
//----------------------统计权值大小
char ch;
while((ch=fgetc(trj_src))!=EOF){
Hufuman.c 源文件
#include "hufuman.h" extern char codelist[256][10]; extern unsigned char uncode[256][2]; //节点插入法 struct node * insert(struct node * root,struct node *s){
unsigned char uncode[256][2]={0}; //----------------------------//--------------------------------------------------------------
int main(){
trj_queue(queue,&src_length); printf("\n---------------------------------------------------------\n"); trj_sort(queue); printf("\n---------------------------------------------------------\n"); huffuman_codelist(queue); printf("\n---------------------------------------------------------\n"); huffman_code(); printf("\n---------------------------------------------------------\n"); huffman_uncode();
//---------------------------------------------/*第步:queue建立二叉树数据结构 * */ //---------------------------------------------void huffuman_codelist(struct node *queue) { int i=0; //21,---------------------------------建立并且初始化二叉树的root,即把排序好的队列 的第一个赋值给root; struct node *root=(struct node *)malloc(sizeof(struct node)); for( i=0;i<256;i++){
struct node * p1,*p2; if(root==NULL)root=s; else{
p1=NULL; p2=root; while(p2 && p2->number < s->number){/*查找插入位置*/
p1=p2; p2=p2->next; } //---------------------------找到了位置,在P1与P2之间 //---------------------------把新节点S的下一个节点指针指向P2,P2的上一个节点的 next指向新节点S //---------------------------P1-S-P2 s->next=p2; if(p1==NULL) root=s; else p1->next=s;
char name;//记录字符
int number;//字符出现的次数 char bit[10];//编码值 struct node *left_child,*right_child,*next; };
struct node * insert(struct node * root,struct node *s);
queue[ch].number++; //----权值加
putchar(ch);
//-------------测试输出字符
src_length[0]++; //----------用于记录文件的长度
}
//-------------测试
for(int i=0;i<256;i++)
if(queue[i].number!=0) printf("%c, %d\n", queue[i].name,queue[i].number);
struct node *right,*left;
//root指向的是链表的首地址,将前两个节点拿出来 left=root; right=root->next;
//将root转移到链表的第三个位置 root=right->next;
root=last_n;//-------------将链表的首地址取出; //----------------------测试 printf("\n---------------------------------------------------------\n"); struct node *p1=root;
if(queue[i].number==0)continue; struct node *link_n=(struct node *)malloc(sizeof(struct node));
link_n->left_child =NULL; link_n->right_child =NULL; link_n->name=queue[i].name; link_n->number=queue[i].number; link_n->bit[0]='\0'; link_n->next=last_n; last_n=link_n; }
if(queue[i].number!=0){ root->left_child =NULL; root->right_child =NULL; root->name=queue[i].name; root->number=queue[i].number; root->next=NULL; root->bit[0]='\0'; i++; break; } } //22,----------------------------------将数组建立成有序链表,初始化左右子树 struct node *last_n=root;//--------------将链表的尾地址取出 for(;i<256;i++){
霍夫曼编码算法 语言:C 开发工具:VS2008 实现流程: 第 1 步: 打开文件, 并且统计文件中各种字符出现的次数 number, 按照出现的 次数从小到大的存入数组 queue[] 第 2 步:顺序的按次数小到大排列到数组中 第 3 步:依据 queue[]建立二叉树数据结构 31,-建立并且初始化二叉树的 root,即把排序好的队列的 第 一 个 赋值给 root。 32,将数组建立成有序链表,初始化左右子树 33,建立二叉树 第 4 步:根据二叉树结构建立编码表,解码表 第 5 步:编码 我们要把文件的字符按照编码表编码为一个二进制流,然后每取 8 个 位装入在一个字符中,并存入文件。 第 5 步:解码 从压缩文件里不断的取出字符作为一个二进制流看待,从左到右挨个 测试为 0 还是为 1,转换为 10 进制值,测试十进制值的大小对应在 解码表里有编码的字符,而且字符表里记录的该字符对应的编码位数 等于你从二进制流里取出来转换为进制值的个数时,转换为对应的解 码表里的字符。
while(p1!=NULL){ printf("%d (%c) ",p1->number,p1->name); p1=p1->next;
} //23,-----------------------------------------------------------建立二叉树
while(root && root->next) {
int trj_compare(const void *a,const void *b){return (*(struct node * )b).number-(*(struct node *)a).number;}
void trj_sort( struct node *aa) {
qsort(aa,256,sizeof(struct node),trj_compare); //-------------测试 //for(int i=0;i<256;i++) // printf("(%c)%d ",aa[i].name,aa[i].number); }
void trj_queue(struct node *queue, long *src_length)
{
FILE *trj_src;
Fra Baidu bibliotek
//----------------------判断文件是否打开成功
if((trj_src=fopen("1.txt","r"))==NULL){printf("open file no %s\n");exit(1); }
void trj_queue(struct node *queue, long *src_length); int trj_compare(const void *a,const void *b); void trj_sort( struct node *aa); void huffuman_codelist(struct node *queue); void huffman_code(); void huffman_uncode();
说明:压缩文件中网页是参考资料
附源代码: Man.c 主函数
#include "hufuman.h" //---------------------------------------------typedef struct node huff_node; typedef struct node *huff_link; huff_node queue[256];//霍夫曼树结构体数组 long src_length;//------------------------记录源文件的字符个数 //--------------------编码对照表 char codelist[256][10]={0};
} return root;//返回链表头指针地址 }
//----------------------------------------------
/*第步:打开文件,并且统计文件中各种字符出现的次数number,按照出现的次
数从小到大的存入数组queue[]中+测试函数
*
*/
//----------------------------------------------
fclose(trj_src); } //------------------------------------------以后经测试后正确
//---------------------------------------------/*第步:顺序的按次数大小排列到数组中+测试函数 * function name1:trj_sort():快排 * function name2:trj_compare():比较两个数的大小 * 形参node a[] : 存放节点的数据 */ //----------------------------------------------
Hufuman.h 头文件
#include<stdio.h> #include<stdlib.h> #include<string.h> #include"iostream"
/*1,定义霍夫曼树的节点 */ //---------------------------------------------struct node{
//----------------------初始化数组
for(int i=0;i<256;i++){
queue[i].name=i;
//初始化字符
queue[i].number=0; //初始化字符出现的次数
}
//
//----------------------统计权值大小
char ch;
while((ch=fgetc(trj_src))!=EOF){
Hufuman.c 源文件
#include "hufuman.h" extern char codelist[256][10]; extern unsigned char uncode[256][2]; //节点插入法 struct node * insert(struct node * root,struct node *s){
unsigned char uncode[256][2]={0}; //----------------------------//--------------------------------------------------------------
int main(){
trj_queue(queue,&src_length); printf("\n---------------------------------------------------------\n"); trj_sort(queue); printf("\n---------------------------------------------------------\n"); huffuman_codelist(queue); printf("\n---------------------------------------------------------\n"); huffman_code(); printf("\n---------------------------------------------------------\n"); huffman_uncode();
//---------------------------------------------/*第步:queue建立二叉树数据结构 * */ //---------------------------------------------void huffuman_codelist(struct node *queue) { int i=0; //21,---------------------------------建立并且初始化二叉树的root,即把排序好的队列 的第一个赋值给root; struct node *root=(struct node *)malloc(sizeof(struct node)); for( i=0;i<256;i++){
struct node * p1,*p2; if(root==NULL)root=s; else{
p1=NULL; p2=root; while(p2 && p2->number < s->number){/*查找插入位置*/
p1=p2; p2=p2->next; } //---------------------------找到了位置,在P1与P2之间 //---------------------------把新节点S的下一个节点指针指向P2,P2的上一个节点的 next指向新节点S //---------------------------P1-S-P2 s->next=p2; if(p1==NULL) root=s; else p1->next=s;
char name;//记录字符
int number;//字符出现的次数 char bit[10];//编码值 struct node *left_child,*right_child,*next; };
struct node * insert(struct node * root,struct node *s);
queue[ch].number++; //----权值加
putchar(ch);
//-------------测试输出字符
src_length[0]++; //----------用于记录文件的长度
}
//-------------测试
for(int i=0;i<256;i++)
if(queue[i].number!=0) printf("%c, %d\n", queue[i].name,queue[i].number);
struct node *right,*left;
//root指向的是链表的首地址,将前两个节点拿出来 left=root; right=root->next;
//将root转移到链表的第三个位置 root=right->next;
root=last_n;//-------------将链表的首地址取出; //----------------------测试 printf("\n---------------------------------------------------------\n"); struct node *p1=root;
if(queue[i].number==0)continue; struct node *link_n=(struct node *)malloc(sizeof(struct node));
link_n->left_child =NULL; link_n->right_child =NULL; link_n->name=queue[i].name; link_n->number=queue[i].number; link_n->bit[0]='\0'; link_n->next=last_n; last_n=link_n; }
if(queue[i].number!=0){ root->left_child =NULL; root->right_child =NULL; root->name=queue[i].name; root->number=queue[i].number; root->next=NULL; root->bit[0]='\0'; i++; break; } } //22,----------------------------------将数组建立成有序链表,初始化左右子树 struct node *last_n=root;//--------------将链表的尾地址取出 for(;i<256;i++){
霍夫曼编码算法 语言:C 开发工具:VS2008 实现流程: 第 1 步: 打开文件, 并且统计文件中各种字符出现的次数 number, 按照出现的 次数从小到大的存入数组 queue[] 第 2 步:顺序的按次数小到大排列到数组中 第 3 步:依据 queue[]建立二叉树数据结构 31,-建立并且初始化二叉树的 root,即把排序好的队列的 第 一 个 赋值给 root。 32,将数组建立成有序链表,初始化左右子树 33,建立二叉树 第 4 步:根据二叉树结构建立编码表,解码表 第 5 步:编码 我们要把文件的字符按照编码表编码为一个二进制流,然后每取 8 个 位装入在一个字符中,并存入文件。 第 5 步:解码 从压缩文件里不断的取出字符作为一个二进制流看待,从左到右挨个 测试为 0 还是为 1,转换为 10 进制值,测试十进制值的大小对应在 解码表里有编码的字符,而且字符表里记录的该字符对应的编码位数 等于你从二进制流里取出来转换为进制值的个数时,转换为对应的解 码表里的字符。
while(p1!=NULL){ printf("%d (%c) ",p1->number,p1->name); p1=p1->next;
} //23,-----------------------------------------------------------建立二叉树
while(root && root->next) {
int trj_compare(const void *a,const void *b){return (*(struct node * )b).number-(*(struct node *)a).number;}
void trj_sort( struct node *aa) {
qsort(aa,256,sizeof(struct node),trj_compare); //-------------测试 //for(int i=0;i<256;i++) // printf("(%c)%d ",aa[i].name,aa[i].number); }
void trj_queue(struct node *queue, long *src_length)
{
FILE *trj_src;
Fra Baidu bibliotek
//----------------------判断文件是否打开成功
if((trj_src=fopen("1.txt","r"))==NULL){printf("open file no %s\n");exit(1); }
void trj_queue(struct node *queue, long *src_length); int trj_compare(const void *a,const void *b); void trj_sort( struct node *aa); void huffuman_codelist(struct node *queue); void huffman_code(); void huffman_uncode();
说明:压缩文件中网页是参考资料
附源代码: Man.c 主函数
#include "hufuman.h" //---------------------------------------------typedef struct node huff_node; typedef struct node *huff_link; huff_node queue[256];//霍夫曼树结构体数组 long src_length;//------------------------记录源文件的字符个数 //--------------------编码对照表 char codelist[256][10]={0};
} return root;//返回链表头指针地址 }
//----------------------------------------------
/*第步:打开文件,并且统计文件中各种字符出现的次数number,按照出现的次
数从小到大的存入数组queue[]中+测试函数
*
*/
//----------------------------------------------
fclose(trj_src); } //------------------------------------------以后经测试后正确
//---------------------------------------------/*第步:顺序的按次数大小排列到数组中+测试函数 * function name1:trj_sort():快排 * function name2:trj_compare():比较两个数的大小 * 形参node a[] : 存放节点的数据 */ //----------------------------------------------