热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

文件压缩解压的哈夫曼树实现

本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。

数据结构课程设计时写的

#include
//使用时间时调用
/
#ifndef T_MS //
#define T_MS //
DWORD start,stop; //
#endif //
/

// 常量定义
/
#ifndef G_C //
#define G_C //
#define N 1000 //
#define MAX 99999 //
#endif //
/
// 统计文件中各个字符时相关结构体
///
#ifndef W_C //
#define W_C //
struct Word_Count{ //
char word ; //字符类型 //
int count ; //字符出现次数 //
}; //
struct Word_Count_Array{ //
struct Word_Count wC[N]; //
int point; //定位指针(指向数组wC中第一个空位) //
}; //
#endif //
///
// 构建Huffuman树相关结构体
/
#ifndef H_T //
#define H_T //
struct Node{ //构建哈夫曼树的节点 //
char word; //
int count; //
struct Node *leftChild,*rightChild; //
int myAdrr,lfAdrr,rgAdrr; //自己|左孩子|右孩子 Adrress //
}; //便于文件中树的生成 //
struct Node_Array{ //
struct Node node[N]; //
int point; //
}; //
struct Dynamic_Array{ //动态数组 //
int dArray[N]; //
int point; //指向数组中第一个空位 //
}; //
struct WordCode{ //存储字符以及其编 //
char word; //字符 //
int code[N]; //Huffu编码 //
int point; //指向数组中第一个空位 //
}; //
struct WordCode_Array{ //存储字符以及其编码 //
struct WordCode wCode[N]; //
int point; //指向数组中wCode第一个空位 //
}; //
struct Dynamic_Array dyArr; //辅组存储编码的动态数组 //
struct WordCode_Array wCArr; //存储字符及其编码 //
int Pos=0; //
#endif //
/

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Function Module : Statistical character frequency *
* *
* Explain : 统计字符频率(Hz),需要缓冲数组buff. *
* *
* @author: luewang *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include"GlobalVCS.h"
/**
*
* Role: compare word to count
*
* Explain: 将传入的字符与存储字符的结构体数组
* 中的字符进行比较,更新字符出现次数
* (Hz)
*
* @return: 无
*
*/
void OperateWC(struct Word_Count_Array* wCA,char word){
int i = 0;
for(; i point ; i++){
if(word==wCA->wC[i].word){
wCA->wC[i].count+=1;
break;
}
}
if(i==wCA->point){
wCA->wC[i].word=word;
wCA->wC[i].count=1;
wCA->point=i+1;
}
}
/**
*
* Role: count word
*
* Explain: 统计各个字符出现的频率(Hz)
*
* @return: 字符频率结构体数组wCA
*
*/
struct Word_Count_Array SingleChar_Hz(char buff[],int n){
struct Word_Count_Array wCA; //存储各个字符出现频数的结构体数组 *
wCA.point=0;
for(int i = 0 ; i OperateWC(&wCA,buff[i]);
}

//控制台打印统计好的字符出现的频率
printf("+----------+-----------+\n");
printf("+ wCA:字符频率统计数组 +\n");
printf("+----------+-----------+\n");
printf("| word | count |\n");
printf("+----------+-----------+\n");
for(int i = 0 ; i printf("|%10c|%11d|\n",wCA.wC[i].word,wCA.wC[i].count);
printf("+----------+-----------+\n");
}

printf("...Over.....OK...\n\n");
return wCA;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Function Module (core code) : Establishment Of Huffuman Tree. *
* *
* Explain : *
* 使用从文件中统计的字符频率的结构体数组,循环先序遍历构建Huffu- *
* -man树,并另外使用结构体数组统计各个字符哈夫曼编码。 *
* *
* @author: luewang *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include"GlobalVCS.h"
#include"GlobalVCS.h"
/**
*
* Role: Sort of Insert
*
* Explain: 利用插入排序将统计好个字符频率的结构体数组wCA
* 进行升序排序.
*
* @return: 返回后续构建树所需要的节点的数组
*
*/
struct Node_Array InsertSort(struct Word_Count_Array *wCA){
int i,j;
int tmpCount;
char tmpChar;
for(i = 1 ; i point ; i++){
tmpCount = wCA->wC[i].count;
tmpChar = wCA->wC[i].word ;
for(j = i ; j > 0 && wCA->wC[j-1].count > tmpCount ; j--){
wCA->wC[j].count = wCA->wC[j-1].count;
wCA->wC[j].word = wCA->wC[j-1].word ;
}
wCA->wC[j].count = tmpCount;
wCA->wC[j].word = tmpChar ;
}
struct Node_Array nodeArray;
for(int i = 0 ; i point ; i++){
nodeArray.node[i].count = wCA->wC[i].count;
nodeArray.node[i].word = wCA->wC[i].word ;
nodeArray.node[i].leftChild = NULL;
nodeArray.node[i].rightChild= NULL;
}
nodeArray.point = wCA->point;
return nodeArray;
}
/**
*
* Role: Sort of the specified interval
* |
* Explain: 利用插入排序指定范围,将构建哈夫曼树所需要的结
* 点的数组进行升序排序.(该函数将会被多次调用)
*
* @return: 无
*
*/
void InsertSortSE(struct Node_Array *nA,int start , int end){
if(end - start > 0){
int i,j;
int tmpCount;
char tmpChar;
struct Node *tmpLeft,*tmpRight;
for(i = start + 1 ; i <= end ; i++){
tmpCount = nA->node[i].count;
tmpChar = nA->node[i].word ;
tmpLeft = nA->node[i].leftChild;
tmpRight = nA->node[i].rightChild;
for(j = i ; j > start && nA->node[j-1].count > tmpCount ; j--){
nA->node[j].count = nA->node[j-1].count;
nA->node[j].word = nA->node[j-1].word ;
nA->node[j].leftChild = nA->node[j-1].leftChild;
nA->node[j].rightChild = nA->node[j-1].rightChild;
}
nA->node[j].count = tmpCount;
nA->node[j].word = tmpChar ;
nA->node[j].leftChild = tmpLeft ;
nA->node[j].rightChild= tmpRight;
}
}
}
/**
*
* Role: Copy Array
*
* Explain: 将数组a的指定范围(start~end)赋值给数组b该范围
*
* @return: 无
*
*/
void ArrayCopy(int a[],int b[],int start,int end){
if(end >= 0 && start >= 0 && end - start >= 0){
for(int i = start ; i <= end ; i++){
b[i] = a[i];
}
}
}
/**
*
* Role: Traverse
*
* Explain: 利用先序遍历构建哈夫曼树(根:Root) 并
* 将遍历的结果放在全局变量wCArr(保存字
* 符及其编码的数组)
*
* @return: 无
*
*/
void Traverse(struct Node* Root){
if(Root->leftChild==NULL&&Root->rightChild==NULL){ //已经到了根节点
Root->myAdrr=Pos;//
Root->rgAdrr=0;//
Root->lfAdrr=0;//
Pos+=1;//

wCArr.wCode[wCArr.point].word = Root->word;
ArrayCopy(dyArr.dArray,wCArr.wCode[wCArr.point].code,0,dyArr.point-1);
wCArr.wCode[wCArr.point].point = dyArr.point;
wCArr.point+=1;
dyArr.point-=1;

return;
}

Root->myAdrr=Pos;//
Pos+=1;//

if(Root->leftChild != NULL){
dyArr.dArray[dyArr.point] = 0;
dyArr.point+=1;
Root->lfAdrr=Pos;//
Traverse(Root->leftChild);
}
if(Root->rightChild != NULL){
dyArr.dArray[dyArr.point] = 1;
dyArr.point+=1;
Root->rgAdrr=Pos;//
Traverse(Root->rightChild);
}

dyArr.point-=1;

return ;
}
/**
*
* Role: Traverse
*
* Explain: 纯粹先序遍历树
*
* @return: 无
*
*/
void TreeT(struct Node* Root,int *count,int *max){
if(Root->leftChild==NULL&&Root->rightChild==NULL){ //已经到了根节点
printf("|%10c|%11d|\n",Root->word,Root->count);
printf("+----------+-----------+\n");

if(*max <*count){
*max = *count;
}

(*count)--;
return ;
}

printf("|%10c|%11d|\n",Root->word,Root->count);
printf("+----------+-----------+\n");

if(Root->leftChild){
(*count)++;
TreeT(Root->leftChild,count,max);
}

if(Root->rightChild){
(*count)++;
TreeT(Root->rightChild,count,max);
}

(*count)--;
return ;
}
int Traverset(struct Node* Root){
//开始时间
start =GetTickCount();

printf("Tree visting is working......\n");

printf("+----------+-----------+\n");
printf("| Visit Tree |\n");
printf("+----------+-----------+\n");
printf("| word | count |\n");
printf("+----------+-----------+\n");

if(Root==NULL){
return 0;
}

int count=1;
int max = 0;

TreeT(Root,&count,&max);

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);

return max;
}
/**
*
* Role: Make a Huffuman Tree
*
* Explain: 根据存储字符频率的结构体数组wCA排序转化
* 为创建哈夫曼树所需要结点数组nodeArray,利
* 用结点数组进行多次排序并且动态增加元素构
* 建哈夫曼树
*
* @return: Root(Huffuman Tree Root)
*
*/
struct Node* HuffumanTreeBuild(struct Word_Count_Array *wCA){
//开始时间
start =GetTickCount();

struct Node_Array nodeArray = InsertSort(wCA); //对统计好的字符频率结构体数组进行排序并将排序放入nodeArray数组中

printf(">>>Building Huffuman tree is working......\n");

struct Node *Root;
for(int i = 1 ; i nodeArray.node[nodeArray.point].count = nodeArray.node[i].count + nodeArray.node[i-1].count;
nodeArray.node[nodeArray.point].leftChild = &(nodeArray.node[i-1]);
nodeArray.node[nodeArray.point].rightChild= &(nodeArray.node[i]) ;
nodeArray.node[nodeArray.point].word='~';

Root = &(nodeArray.node[nodeArray.point]);

nodeArray.point +=1;
InsertSortSE(&nodeArray,i+1,nodeArray.point-1);
if(i+1 == nodeArray.point||i+1 == nodeArray.point - 1){
break;
}
}

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);

//开始时间
start =GetTickCount();

printf("Encoding is working......\n");

Traverse(Root); //遍历过程中将每个字符类型code编码存储存入全局变量wCArr中

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);

return Root;
}
/**
*
* Role: Show Huffuman Code
*
* Explain: 显示(存放在全局变量wCA中的)字符编码
*
* @return: 无
*
*/
void ShowHuffumanCode(){
//开始时间
start =GetTickCount();

printf("+----------+---------------------------+\n");
printf("+ Huffuman Code +\n");
printf("+----------+---------------------------+\n");
printf("| word | code |\n");
printf("+----------+---------------------------+\n");

for(int i = 0 ; i char str = wCArr.wCode[i].word;

printf("|%-10c|",str);

int j;
for(j = 0 ; j printf("%d ",wCArr.wCode[i].code[j]);
}

for(int k = 0 ; k <27-2*j ; k++){
printf(" ");
}
printf("|\n");
printf("+--------------------------------------+\n");

}

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);

}
//辅组二叉树格式二维数组形成 (树枝高度)
int F(int x){
if(x == 1){
return 1;
}else if(x == 2){
return 2;
}
if(x >= 3){
return 2*F(x-1) + 1;
}
return -1;
}
//辅组二叉树格式二维数组形成
int HelpFunc(int x,int base1,int base2,int spare){
if(x == 2){
return base1;
}else if(x == 3){
return base2;
}
if(x > 3){
return 2*HelpFunc(x-1,base1,base2,spare) + spare;
}
return -1;
}
/**
*
* Role: Draw binary tree in console
*
* Explain: 绘制二叉树在控制台
*
* @return: void
*
*/
void PaintBiTree(struct Node* Root){
//开始时间
start =GetTickCount();

int deep = Traverset(Root); //树的深度
int branch; //枝长
int baseW = HelpFunc(deep,4,11,1);//数组宽度{ f(2) = 4 f(3) = 11 f(n) = 2*f(n-1) + 1 (n>=2) }
int deepH = HelpFunc(deep,3,6,0); //数组高度{ f(2) = 3 f(3) = 6 f(n) = 2*f(n-1) (n>=2) }

//printf("deepH = %d baseW = %d\n",deepH,baseW);

struct Node *treeDim[deepH][baseW],*tmpL,*tmpR;

tmpL =(struct Node*)malloc(sizeof(struct Node));
tmpR =(struct Node*)malloc(sizeof(struct Node));
tmpL->word='\\';
tmpR->word='\/';
for(int i = 0 ; i for(int j = 0 ; j treeDim[i][j]=NULL;
}
}

treeDim[0][baseW/2] = Root;


//二叉树格式创建
int floor;
for(int i = 0,floor = 1 ; floor <= deep; floor++,i+=branch+1){
for(int j = 0 ; j if(treeDim[i][j]!=NULL){
if(treeDim[i][j]->leftChild!=NULL){ //左孩子
branch = F(deep - floor );
for(int k = 1 ; k <= branch ; k++){
treeDim[i+k][j-k] = tmpL;
}
treeDim[i+branch+1][j-branch-1] = treeDim[i][j]->leftChild;
}
if(treeDim[i][j]->rightChild!=NULL){ //右孩子
branch = F(deep - floor);
for(int k = 1 ; k <= branch ; k++){
treeDim[i+k][j+k] = tmpR;
}
treeDim[i+branch+1][j+branch+1] = treeDim[i][j]->rightChild;
}
}
}
}

//根据二维数组打印二叉树格式
for(int i = 0 ; i for(int j = 0 ; j if(treeDim[i][j]==NULL){
printf(" ");
}else if(treeDim[i][j]==tmpL){
printf("\/");
}else if(treeDim[i][j]==tmpR){
printf("\\");
}else if(treeDim[i][j]!=NULL){
printf("%c",treeDim[i][j]->word);
}
}
printf("\n");
}

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);

getchar();
}

/* * * * * * * * * * * * * * * * * * * * * * * *
* *
* Function Module : <> File Operation *
* *
* Explain : 文件操作模块 *
* *
* @author: luewang *
* *
* * * * * * * * * * * * * * * * * * * * * * * */
#include"GlobalVCS.h"
/**
*
* Role: read word from src to buff
*
* Explain: 从文件中读入字符并将其存入buff数组中
*
* @return: buff
*
*/
char* FileInputStream(char* src){
//开始时间
start =GetTickCount();

FILE *file;
char buff[MAX];

if((file = fopen(src,"r"))==NULL){
printf("Error : Open File %s is Faile To Open!!! \n",src);
}

printf(">>>Open File directory is : %s \n",src);

int ch , count;
printf("\n-+-+-+-+-+-+-+Content-+-+-+-+-+-+-+-\n"); //显示从文件中读出的内容
for(count = 0;(ch=fgetc(file))!=EOF;count++){
buff[count] = ch;
printf("%c",ch);
}
printf("\n-+-+-+-+-+-+-+-End+-+-+-+-+-+-+-+-+-+-\n");

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);

fclose(file);
return buff;
}
/**
*
* Role: file visit and save tree
*
* Explain: 先序遍历保存构建好的哈夫曼树
*
* @return: 无
*
*/
void SaveTreeVisit(struct Node *Root,FILE *file){
if(Root->leftChild==NULL&&Root->rightChild==NULL){ //叶子节点

printf("|%10c|%11d|%12d|%12d|%12d|\n",Root->word,Root->count,Root->myAdrr
,Root->lfAdrr,Root->rgAdrr);
printf("+----------+-----------+------------+------------+------------+\n");

fwrite(Root,sizeof(struct Node),1,file);

return;
}

printf("|%10c|%11d|%12d|%12d|%12d|\n",Root->word,Root->count,Root->myAdrr
,Root->lfAdrr,Root->rgAdrr);
printf("+----------+-----------+------------+------------+------------+\n");

fwrite(Root,sizeof(struct Node),1,file);
SaveTreeVisit(Root->leftChild,file);
SaveTreeVisit(Root->rightChild,file);
}
/**
*
* Role: save huffuman tree to file
*
* Explain: 将根节点是Root的树保存到dir路径文件中.
*
* @return : 无
*
*/
void SaveHuffumanTree(char *dir,struct Node *Root){
//开始时间
start =GetTickCount();

FILE *file;

if((file = fopen(dir,"wb+")) == NULL){
printf("Error : Save File %s is Faile To Open!!! \n",dir);
}
printf(">>>Save File directory is : %s \n",dir);

printf("+----------+-----------+------------+------------+------------+\n");
printf("| word | count | myAdrr | lfAdrr | rgAdrr |\n");
printf("+----------+-----------+------------+------------+------------+\n");

SaveTreeVisit(Root,file);

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);

fclose(file);
}
/**
*
* Role: File Visit And Get Tree
*
* Explain: 从文件中取出哈夫曼树节点信息放入tmpRoot数组中
* 通过tmpRoot数组中构建哈夫曼树 , tmpRoot数组每
* 个元素存储了左右孩子和自己的地址(int)
*
* @return : tmpRoot头结点(哈夫曼树根结点)
*
*/
struct Node* GetTreeVisit(FILE *file){
int point = 0;
struct Node tmpRoot[N];
while(fread(&tmpRoot[point],sizeof(struct Node),1,file)!=NULL){

if(tmpRoot[point].lfAdrr==0&&tmpRoot[point].rgAdrr==0){
printf("|%10c|%11d|\n",tmpRoot[point].word,tmpRoot[point].count);
printf("+----------+-----------+\n");
}

point+=1;
}

for(int i = 0 ; i if(tmpRoot[i].lfAdrr == 0){
tmpRoot[i].leftChild = NULL;
}else if(tmpRoot[i].lfAdrr != 0){
for(int j = i + 1 ; j if(tmpRoot[j].myAdrr == tmpRoot[i].lfAdrr){
tmpRoot[i].leftChild = &tmpRoot[j];
break;
}
}
}
if(tmpRoot[i].rgAdrr == 0){
tmpRoot[i].rightChild = NULL;
}else if(tmpRoot[i].rgAdrr != 0){
for(int j = i + 1 ; j if(tmpRoot[j].myAdrr == tmpRoot[i].rgAdrr){
tmpRoot[i].rightChild = &tmpRoot[j];
break;
}
}
}
}
return tmpRoot;
}
/**
*
* Role: Get Huffuman Tree
*
* Explain: 从指定(*.dat)文件中获取获取哈夫曼树,给该树
* 根结点Root赋值 .
*
* @return : 无
*
*/
void GetHuffumanTree(char *dir,struct Node **Root){
//开始时间
start =GetTickCount();
FILE *file;

file = fopen(dir,"rb+");
if(file==NULL){
printf("Error : Get File Open is failed To Open : %s\n",dir);
}
printf(">>>Get File directory is : %s \n",dir);

printf("+----------+-----------+\n");
printf("| word | count |\n");
printf("+----------+-----------+\n");

*Root = GetTreeVisit(file); //哈夫曼树根结点

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);

fclose(file);
}
/**
*
* Role: word zip
*
* Explain: 将指定字符ch根据哈夫曼树编码(wCArr)进行压缩至
* 文件 huffuFile 中.
*
* @return : 无
*
*/
void ZIP(int ch,FILE *huffuFile){
for(int i = 0 ; i if(ch == wCArr.wCode[i].word){
for(int j = 0 ; j
printf("%d",wCArr.wCode[i].code[j]);

fputc(wCArr.wCode[i].code[j]+48,huffuFile);
}
}
}
}
/**
*
* Role: file zip
*
* Explain: 指定文件路径src进行文件压缩至一个新的文
* 件中huffuFile
*
* @return : 无
*
*/
void FileZip(char* src){
//开始时间
start =GetTickCount();

FILE *file,*huffuFile;

if((file = fopen(src,"r+")) == NULL){
printf("Error : File %s Open is failed!!!\n",src);
}
printf(">>>ZIP File directory is : %s \n",src);

char dir[strlen(src)+5];
strcpy(dir,src);
dir[strlen(dir)-4]='\0';
strcat(dir,"_hf.txt");

if((huffuFile = fopen(dir,"w+")) == NULL){
printf("Error : Zipped File %s Open is failed!!!\n",dir);
}
printf(">>>Zipped File directory is : %s \n",dir);

int ch;

printf("\n-+-+-+-fake Binary l stream-+-+-+-+-\n");
while((ch=fgetc(file))!=EOF){
ZIP(ch,huffuFile);
}
printf("\n-+-+-+-+-+-+-+-End+-+-+-+-+-+-+-+-+-\n");

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);

fclose(file);
fclose(huffuFile);
}
/**
*
* Role: file unzip
*
* Explain: 将指定哈夫曼 0 1 文件(huffuFile)进行哈夫曼树解
* 码存入file文件中
*
* @return : 无
*
*/
void UnZIP(struct Node *Root,FILE *huffuFile,FILE *file){
struct Node *root = Root; //哈夫曼树根结点
int ch;
while((ch=fgetc(huffuFile))!=EOF){
printf("%c",ch);
if(ch - 48 == 0){
root=root->leftChild;
}else if(ch - 48 == 1){
root=root->rightChild;
}

if(root->rightChild==NULL&&root->leftChild==NULL){ //已经到了叶节点
fputc(root->word,file);
root=Root; //回到根节点
}
}
}
/**
*
* Role: file unzip
*
* Explain: 对给定文件路径进行哈夫曼树解压 Root:
* 为哈夫曼树根结点
*
* @return : 无
*
*/
void FileUnZip(char* dir,struct Node *Root){
//开始时间
start =GetTickCount();

FILE *file,*huffuFile;

if((huffuFile = fopen(dir,"r+")) == NULL){
printf("Unzip File Open is failed : %s\n",dir);
}
printf(">>>Unzip File directory is : %s \n",dir);

char Dir[strlen(dir)];
strcpy(Dir,dir);
Dir[strlen(dir)-7]='\0';
strcat(Dir,"`.txt");

printf("After UnZip FIle Is %s\n",Dir);

if((file= fopen(Dir,"w+")) == NULL){
printf("Unzipped File Open is failed : %s\n",Dir);
}
printf(">>>Unzipped File directory is : %s \n",Dir);

UnZIP(Root,huffuFile,file);
printf("\n");

//结束时间
stop =GetTickCount();
printf("...Over.....OK...(%lld ms)\n\n",stop-start);
fclose(file);
fclose(huffuFile);
}


#include
#include
#include
#include
#include"FileOperate.h"
#include"WordHzCount.h"
#include"HuffuTreeBuild.h"
//文件压缩项
void ZIPFILE(char *src){
char dir[strlen(src)+1]; //保存哈夫曼树的文件路径
strcpy(dir,src);
dir[strlen(dir)-4]='\0';
strcat(dir,".dat");

char *buff = FileInputStream(src); //获取指定文件中的资源
struct Word_Count_Array wCA = SingleChar_Hz(buff,strlen(buff));//统计指定资源文件中的字符出现频率
struct Node* Root = HuffumanTreeBuild(&wCA); //构建哈夫曼树Root 并且将字符编码存入全局wCA中
SaveHuffumanTree(dir,Root); //将哈夫曼树存入文件中去
ShowHuffumanCode(); //展示字符编码
PaintBiTree(Root); //展示哈夫曼树

FileZip(src); //文件压缩

}
//文件解压项
void UNZIPFILE(char *dir){
char huffile[strlen(dir)+10]; //保存哈夫曼树的文件路径
strcpy(huffile,dir);
huffile[strlen(huffile)-7]='\0';
strcat(huffile,".dat");

struct Node *root; //哈夫曼树根结点
GetHuffumanTree(huffile,&root);

FileUnZip(dir,root); //文件解压

PaintBiTree(root); //展示哈夫曼树
}
//帮助
void HELP(){
printf("\nYou need to enter two parameters.\n");
printf("The first parameter is the functional option(the following values are available).\n");
printf("'-zip' Or '-unzip' which means decompression and compression.\n");
printf("The second parameter is the filepath option(such as : 'D:\\a.txt').\n");
printf("It is important to note that the input format cannot have any extra Spaces, and the format is '-option' 'path'\n");
}
int main() {

printf("Welcome to Huffman coding by Wang.\nNotice : you can use the '-help' for help.\nLanguage: C \nAuthor : luewang \nVersion : 1.0\n");
char option[N];
char path[N];
while(1){
printf("WHuff>>>");
scanf("%s",option);

if(strcmp(option,"-help")==0){
HELP();
}else if(strcmp(option,"-zip")==0){
scanf("%s",path);
ZIPFILE(path);
}else if(strcmp(option,"-unzip")==0){
scanf("%s",path);
UNZIPFILE(path);
}else if(strcmp(option,"exit")==0){
exit(0);
}else{
printf("Error: Please input the correct format. You can also use '-help' to view the help document\n");
}
}
return 0;
}


推荐阅读
  • 在多线程编程环境中,线程之间共享全局变量可能导致数据竞争和不一致性。为了解决这一问题,Linux提供了线程局部存储(TLS),使每个线程可以拥有独立的变量副本,确保线程间的数据隔离与安全。 ... [详细]
  • 本次考试于2016年10月25日上午7:50至11:15举行,主要涉及数学专题,特别是斐波那契数列的性质及其在编程中的应用。本文将详细解析考试中的题目,并提供解题思路和代码实现。 ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • Codeforces Round #566 (Div. 2) A~F个人题解
    Dashboard-CodeforcesRound#566(Div.2)-CodeforcesA.FillingShapes题意:给你一个的表格,你 ... [详细]
  • 本题通过将每个矩形视为一个节点,根据其相对位置构建拓扑图,并利用深度优先搜索(DFS)或状态压缩动态规划(DP)求解最小涂色次数。本文详细解析了该问题的建模思路与算法实现。 ... [详细]
  • 毕业设计:基于机器学习与深度学习的垃圾邮件(短信)分类算法实现
    本文详细介绍了如何使用机器学习和深度学习技术对垃圾邮件和短信进行分类。内容涵盖从数据集介绍、预处理、特征提取到模型训练与评估的完整流程,并提供了具体的代码示例和实验结果。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 作为一名 Ember.js 新手,了解如何在路由和模型中正确加载 JSON 数据是至关重要的。本文将探讨两者之间的差异,并提供实用的建议。 ... [详细]
  • 本文详细介绍了如何解决MyBatis中常见的BindingException错误,提供了多种排查和修复方法,确保Mapper接口与XML文件的正确配置。 ... [详细]
  • 脑机接口(BCI)技术正逐步将科幻变为现实,从帮助听障人士恢复听力到使瘫痪者重新站立,甚至可能将多年的学习过程压缩至瞬间。本文探讨了这一前沿技术的现状、挑战及其未来前景。 ... [详细]
  • 本文介绍了一种解决二元可满足性(2-SAT)问题的方法。通过具体实例,详细解释了如何构建模型、应用算法,并提供了编程实现的细节和优化建议。 ... [详细]
  • 本题旨在通过给定的评级信息,利用拓扑排序和并查集算法来确定全球 Tetris 高手排行榜。题目要求判断是否可以根据提供的信息生成一个明确的排名表,或者是否存在冲突或信息不足的情况。 ... [详细]
  • 本文介绍了Linux系统中的文件IO操作,包括文件描述符、基本文件操作函数以及目录操作。详细解释了各个函数的参数和返回值,并提供了代码示例。 ... [详细]
  • 哈密顿回路问题旨在寻找一个简单回路,该回路包含图中的每个顶点。本文将介绍如何判断给定的路径是否构成哈密顿回路。 ... [详细]
author-avatar
人散心未散1
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有