恋霄愿 - 云代码空间
—— 倾我一生一世恋
/*-----头文件------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <malloc.h>
/*----定义宏-----*/
#define MAXNUM 10000
#define SIZE 100
#define ERROR 0
#define TRUE 1
#define OK 1
#define MAX 128 //叶子节点个数(对应ASCII码)
#define MT 2*MAX-1 //树的节点个数
/*-----由动态输入建立哈夫曼树------*/
//哈弗曼树的数据结构
typedef struct HuffmanTNode{
char ch; // 要编码的字符表示
unsigned int weight; // 结点的权值
unsigned int parent,lchild,rchild;//双亲,左孩子,右孩子
}HuffmanTNode,*Put_HuffmanTree;
typedef char **HuffmanCode; //哈弗曼结点的数据结构
//读文件的哈弗曼树的结构定义
typedef struct HNode{
int weight; //权值
int parent; //双亲位置
int LChild; //左孩子位置
int RChild; //右孩子位置
}HTNode,HuffmanTree[MT+1]; //结构体数组 (相当与指针)
/*---文件编码的数据结构----*/
typedef struct Node{
char letter;//字符
char* code;//编码
int w;//权值(对应文章中字母(letter)出现次数)
}Huffman[MAX+1];//结构体数组储存权值的顺序存储结构
//定义全局变量
HuffmanTree ht; //存储哈夫曼树
Put_HuffmanTree HT; //哈弗曼树(输入构建)
HuffmanCode HC; //哈弗数据
Huffman qz; //权值相关信息
int weight[MT+1] = {0}; //存储临时权值
int t = 0; //存储
/*********************函数声明**********************/
void select(int *s1,int *s2);//建立哈夫曼树时的选择权值
void Put_Select(int n, int *s1, int *s2);//动态建立哈夫曼树结构的选择算法
int ReadWeight();//从文件中读文章获得权值,返回权值个数
void CrtHuffmanTree();//建立哈夫曼树
int HuffmanCoding(int n);//哈夫曼数(由键盘输入算法)
void Encoding();//编码
void HuffmanCodePrint();//打印
void WriteTree();//向文件中写入哈夫曼树
void Initialization();//初始化
void WriteCode();//向文件中写入编码
void Decoding();//译码
int find_letter(char ch);//查找字符
int find_code(char s[]);//查找编码
void InitTree();//初始化树
void TreePrinting();//打印哈夫曼树
void Menu();//菜单
void putTree_menu();//二级界面
void load();//loading
void Encoding_put(int n);//对字符串进行编码
void Decoding_put(int n);//对编码进行译码
void _print(FILE *fp,HNode hft,int n);
void Writedata_HT(int n)
/*------依次选出两个最小的值-------*/
void Put_Select(int n, int *s1, int *s2){
int i, ti, t = MAXNUM;
for(i = 1; i <= n; i++){
if(!HT[i].parent){
if(t > HT[i].weight){
t = HT[i].weight;//t最后为最小的weight
ti = i;
}
}
}
*s1 = ti;
t = MAXNUM;
ti = 0;
for(i = 1; i <= n; i++){
if((!HT[i].parent) && i!=*s1){ //parent为0
if(t > HT[i].weight){
t = HT[i].weight;
ti = i;
}
}
}
*s2 = ti;
}
/*------------------编译器的一级菜单--------------------------*/
void Menu(){
InitTree();
printf("********************★欢迎来到哈夫曼编码译码器★************************\n");
printf("|+|■■■■■■■■■■■哈夫曼编码译码器■■■■■■■■■■■■■|+|\n");
printf("|+|■\a\t ★1-请先建立哈夫曼树(文件初始化)\t \t■|+|\n");
printf("|+|■ \t ★2-进行编码(根据文件) \t \t■|+|\n");
printf("|+|■ \t ★3-对其译码(由文件载入编码)\t \t■|+|\n");
printf("|+|■ \t ★4-对哈夫曼编码文件保存打印\t \t■|+|\n");
printf("|+|■ \t ★5-打印哈夫曼树\t \t■|+|\n");
printf("|+|■ \t ★6-进行哈夫曼的一些树操作(键盘输入建立哈夫曼) \t■|+|\n");
printf("|+|■\a\t ★7-完成工作请退出\t \t■|+|\n");
printf("|+|■\a\t ★8-(附录)打开需要编码的文件进行编辑\t \t■|+|\n");
printf("|+|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■|+|\n");
printf("************************************************************************\n");
}
/*---二级菜单-----*/
void putTree_menu(){
printf("**********************★二级目录菜单★********************************\n");
printf("*================1-★先输入结点和权值建立哈夫曼树====================*\n");
printf("*================2-★显示每个结点的哈弗曼编码========================*\n");
printf("*================3-★输入字符串进行编码并显示保存====================*\n");
printf("*================4-★对编码进行译码并显示保存========================*\n");
printf("*================5-★将哈夫曼以及编码结果保存到文件data.txt==========*\n");
printf("*================0-★退出操作(退出程序/返回主目录)===================*\n");
printf("**********************************************************************\n");
}
/* ----loading函数--------*/
void load(){
printf("loading");
for(int i=1;i<=5;i++){
printf("...");
Sleep(100);//windows.h下的休眠函数 100 = 0.1秒
}
printf("\n就要进入啦!\n");
Sleep(1000);
}
/*---------初始化树--------*/
void InitTree(){
ht[0].weight = 0;//标志哈夫曼树是否存在
qz[0].w = 0; //标志是否编码
}
/*---------哈夫曼算法创建哈夫曼树--------*/
int HuffmanCoding(int n){
int i,s1,s2;
int w[n+1];//weight 0下标不使用
char title;//标志位
char ch[n+1];//由键盘输入的要编码的字符
while(n <= 1){
printf("输入的数据有误,请重新输入:\n");
scanf("%d",&n);
}
int m = 2 * n - 1;
while(title = getchar() != '\n');//空格后停止输入
printf("■请输入各字符(用空格分开):");
for(i=1; i<=n; i++){
scanf("%c",&ch[i]);
getchar();
}
printf("■请输入各权值(用空格分开):");
for(i = 1; i <= n; i++){
scanf("%d",&w[i]);
getchar();
}
HT = (Put_HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号节点不使用
for(i = 1 ; i <= n ; i++){
HT[i].ch = ch[i];
HT[i].weight = w[i];
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}
for( ; i <= m ; i++){
HT[i].ch = '#';//其它中间生成的结点用#表示
HT[i].weight = 0;
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}
for(i = n+1 ; i <= m ; i++){
Put_Select(i-1,&s1,&s2);
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
printf("\n■生成的哈夫曼树为(其中生成树时生成的结点用“# ”表示):");
printf("\n");
printf("char weight parent lchild rchild\n");
for(i = 1; i <= m; i++){
printf("%2c %5d %7d %7d %7d\n", HT[i].ch, HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
}
return OK;
}
/*------从叶子到根逆向求每个字符的哈夫曼编码 -------*/
void HuffmanCoding_print(int n){
int i = 0;
int m = 2 * n - 1 ;
HC = (HuffmanCode)malloc((n+1) * sizeof(char*));//分配n个字符编码的头指针向量
if(HC == NULL){
printf("动态分配内存失败!!!");
}
char *cd;
cd = (char *)malloc(n * sizeof(char));//分配求编码的工作空间
cd[n-1] = '\0';//编码结束符
printf("■其编码表为:\n");
int c,f,start;
for(i = 1 ; i <= n ; i++){//逐个字符求哈夫曼编码
start = n - 1;//编码结束符的位置
for(c = i ,f = HT[i].parent ; f != 0 ; c = f,f = HT[f].parent){
if(HT[f].lchild == c){
cd[--start] = '0';
}else{
cd[--start] = '1';
}
}
HC[i] = (char *)malloc((n - start)*sizeof(char)); //为第i个字符编码分配空间
strcpy(HC[i] , &cd[start]);//从cd复制编码(串)到HC
printf("其结点为%c的编码为:", HT[i].ch);
puts(HC[i]);
}
free(cd);//释放工作空间
}
/*--------------无栈非递归遍历哈夫曼树求哈夫曼编码-----------*/
/*int HuffmanCoding_print(int n){
int cdlen = 0 , p ,i;
int m = 2 * n - 1;
p = m;
char *cd;
for(i = 1;i <= m;++i){
HT[i].weight = 0;
}
while(p){
if(HT[p].weight == 0){
HT[p].weight = 1;
if(HT[p].lchild != 0){
p = HT[p].lchild;
cd[cdlen++] = '0';
}else if(HT[p].rchild == 0){
HC[p] = (char*)malloc((cdlen+1)*sizeof(char));
cd[cdlen] = '\0';
strcpy(HC[p] , cd);
}
}else if(HT[p].weight == 1){
HT[p].weight == 2;
if(HT[p].rchild != 0){
p = HT[p].rchild;
cd[cdlen++] = '1';
}
}else{
HT[p].weight = 0;
p = HT[p].parent;
--cdlen;
}
}
printf("其结点为%c的权值为:",HT[i].ch,HC[i]);
return OK;
} */
/*---------对字符串进行编码-------------*/
void Encoding_put(int n){
char *s,title,m;
int i ,j , x;
FILE *fp_Ec;
printf("请确定字符串的长度m:");
scanf("%d",&m);
s = (char *)calloc(m , sizeof(char));
if(s == NULL){
printf("为字符串s内存分配失败!!!");
getchar();
exit(0);
}
int len = (int)(sizeof(s)/sizeof(s[0]));
printf("字符串的长度为:%d",len);
while(title = getchar() != '\n');//使其回车可退出循环
printf("\n\a请输入字符串:\n");
for(i = 0;i < len;i++){
scanf("%s",&s[i]);
}
printf("编码结果为:\n");
for(i = 0;s[i] != '\0'&&i < len;i++){
for(j = 1;j <= n;j++){
if(s[i] == HT[j].ch){
//printf("%s", HC[j]);
puts(HC[j]);
continue ;
}
}
}
if((fp_Ec = fopen("F:\\HuffmanTree\\Ec_putingFile.txt","wb+")) == NULL){
printf("Ec_puingFile打开失败,请确认文件是否出错!!!");
getch();
exit(0);
}else{
printf("文件打开成功现将编码载入文件:");
fprintf(fp_Ec , "\n编码结果为:");
for(i = 0;s[i] != '\0'&&i < len;i++){
for(j = 1;j <= n;j++){
if(s[i] == HT[j].ch){
fprintf(fp_Ec ,"%s",HC[j]);
//fputs(HC[j] , fp_Ec);
continue ;
}
}
}
}
fclose(fp_Ec);
printf("是否要查看编码!0-否/1-是");
scanf("%d",&x);
if(x == 1){
if((fp_Ec = fopen("F:\\HuffmanTree\\Ec_putingFile.txt","r")) == NULL){
printf("Ec_puingFile打开失败,请确认文件是否出错!!!");
getch();
exit(0);
}else{
char ch0;
ch0 = fgetc(fp_Ec);
while(ch0 != EOF){
putchar(ch0);
ch0 = fgetc(fp_Ec);
}
}
}
fclose(fp_Ec);
printf("\n");
}
/*---------对编码后的字符串进行译码--------*/
void Decoding_put(int n){
char s[SIZE], title;
int i = 0, p = 2*n-1 ,y;//p在根节点位置;
FILE *fp_Dc;
while(title = getchar() != '\n');
printf("\a\n■请输入编码(编码中间无空格):\n");
scanf("%s", s);
printf("■输出译码结果为:\n");
for(i = 0; s[i] != '\0'; i++){
if(s[i]=='0')
p=HT[p].lchild;
if(s[i]=='1')
p=HT[p].rchild;
if(p<=n){
printf("%c", HT[p].ch);
p=2*n-1;
}
}
if((fp_Dc = fopen("F:\\HuffmanTree\\Dc_putingFile.txt","wb+")) == NULL){
printf("Dc_puingFile打开失败,请确认文件是否出错!!!");
getch();
exit(0);
}else{
printf("\n文件打开成功现将译码载入文件:");
fprintf(fp_Dc , "\n译码结果为:");
for(i = 0; s[i] != '\0'; i++){
if(s[i]=='0')
p=HT[p].lchild;
if(s[i]=='1')
p=HT[p].rchild;
if(p<=n){
fprintf(fp_Dc , "%c",HT[p].ch);
p=2*n-1;
}
}
}
fclose(fp_Dc);
printf("是否要查看编码!0-否/1-是");
scanf("%d",&y);
if(y == 1){
if((fp_Dc = fopen("F:\\HuffmanTree\\Dc_putingFile.txt","r")) == NULL){
printf("Dc_puingFile打开失败,请确认文件是否存储出错!!!");
getch();
exit(0);
}else{
char ch0;
ch0 = fgetc(fp_Dc);
while(ch0 != EOF){
putchar(ch0);
ch0 = fgetc(fp_Dc);
}
}
}
fclose(fp_Dc);
printf("\n");
}
/*------树的初始化-------*/
void Initialization(){
ht[0].weight = 1; //初始化标志,说明哈夫曼树以存在
t=ReadWeight(); //读取权值
CrtHuffmanTree(); //建立哈夫曼树
WriteTree(); //将哈夫曼树写入文件
printf("哈弗曼树'初始化'成功!\n");
}
/*------将哈夫曼树写入文件-------*/
void WriteTree(){
FILE *fp;//hfmTree 文件指针
int m = 2*t-1;
int i;
//打开文件
if((fp=fopen("F:\\HuffmanTree\\huffmanTreeopen.txt","w")) == NULL){
printf("open huffmanTreeopen.txt--file error\n");
exit(0);
}//else printf("open huffmanTreeopen.txt--file sucess!\n");
//哈夫曼树写入文件
for(i=1;i<=m;i++)
fprintf(fp,"%d %d %d %d\n",ht[i].weight,ht[i].parent,ht[i].LChild,ht[i].RChild);
//关闭文件
if(fclose(fp)){
printf("\a close huffmanTreeopen.txt--file error!\n");
exit(0);
}//else printf("close huffmanTreeopen.txt--file success!\n");
}
/*-----------选择s1,s2-----------*/
void select(int n,int *s1,int *s2){
int i,min;
//寻找一个没有双亲的节点,找到后退出循环
for(i=1; i<=n; i++){
if(ht[i].parent == 0){
min = i;
break;
}
}
//寻找最小无双亲节点
for(i=1; i<=n; i++){
if(ht[i].weight<ht[min].weight && ht[i].parent == 0)
min = i;
}
*s1 = min;
//寻找次最小无双亲节点
for(i=1; i<=n; i++){
if(ht[i].parent == 0 && i != *s1){
min = i;
break;
}
}
for(i=1; i<=n; i++){
if(ht[i].weight < ht[min].weight && i != *s1 && ht[i].parent == 0)
min = i;
}
*s2 = min;
}
/*-----读取文章,获取权值--------*/
int ReadWeight(){
//返回权值个数
int n=1;
FILE *fp;
char ch;
//打开文件
if((fp=fopen("F:\\HuffmanTree\\huffmanToBeTran.txt","r")) == NULL){
printf("\a open huffmanToBeTran.txt--file error!\n");
exit(0);
}//else printf("open huffmanToBeTran.txt--file sucess!\n");
//读取字符
while(!feof(fp)){//一直循环,知道文件结束
ch = fgetc(fp);
if(ch != EOF){
weight[ch]++;//依次读取字符增加权值
}
}
//关闭文件
if(fclose(fp)){
printf("\a close huffmanToBeTran.txt--file error!\n");
exit(0);
}//else printf("close huffmanToBeTran.txt--file success!\n");
//临时权值转化到qz[]中
for(int i=0;i<MT;i++){
//printf("%d ",weight[i]);
if(weight[i]>=1){
qz[n].letter = (char)i;
qz[n].w = weight[i];
n++;
}
}
return n-1;//n从1开始计数
}
/*----建立哈夫曼树--------*/
void CrtHuffmanTree(){
int i,s1,s2,m = 2*t-1;
//*初始化*//
for(i=1; i<=t; i++){//第1到n个位置放置n个叶子节点
ht[i].weight = qz[i].w;
ht[i].parent = ht[i].LChild = ht[i].RChild = 0;
}
for(i=t+1;i<=m;i++){//第n+1个到第m个位置放置非叶子节点
ht[i].weight = ht[i].parent = ht[i].LChild = ht[i].RChild = 0;
}
//*建立*//
for(i=t+1; i<=m; i++){
select(i-1,&s1,&s2);
//printf("s1 = %d,s2 = %d\n",s1,s2);
ht[i].weight = ht[s1].weight + ht[s2].weight;
ht[s1].parent = ht[s2].parent = i;
ht[i].LChild = s1;
ht[i].RChild = s2;
}
}
/*------哈夫曼编码 ---------*/
void Encoding(){
if(ht[0].weight == 0){
printf("没初始化!!\n");
Sleep(2000);//挂起一段时间
return;
}
int i,start,c,p;
char *cd;
cd = (char*)malloc(t*sizeof(char));
cd[t-1]='\0';
for(i=1; i<=t; i++){//对n个叶子节点进行编码
start = t-1;//定位到临时编码数组的最后一位
c = i;//记录当前节点位置
p = ht[i].parent;//记录当前节点的双亲位置
while(p!=0){
--start;
if(ht[p].LChild == c)//若该节点是其双亲的左孩子,则编码0
cd[start]='0';
else//若为右孩子则编码1
cd[start]='1';
c = p;//下次循环的准备条件
p = ht[p].parent;
}
qz[i].code=(char*)malloc((t-start)*sizeof(char));
strcpy(qz[i].code,&cd[start]);
}
free(cd);
//以上代码完成编码工作
/*测试代码
for(i=1;i<=n;i++)
printf("%c %d %s\n",hc[i].letter,hc[i].w,hc[i].code);*/
//将编码写入文件
WriteCode();
/*for(i=1;i<=n;i++){
printf("%s\n",hc[i].code);
}*/
qz[0].w = 1;//标志以编码
printf("编码成功啦……^&^!\n");
}
/*-----编码写入的函数---------*/
void WriteCode(){
FILE *fp_code,*fp_text;
char ch;
int i;
//打开编码存储文件
if((fp_code=fopen("F:\\HuffmanTree\\HuffmanTreeCode.txt","w")) == NULL){
printf("\a open HuffmanTreeCode.txt--file error !\n");
exit(0);
}//else printf("open HuffmanTreeCode.txt--file success!\n");
//打开需要编码的文本文件
if((fp_text=fopen("F:\\HuffmanTree\\huffmanToBeTran.txt","r")) == NULL){
printf("\a open huffmanToBeTran.txt ……file error !\n");
exit(0);
}//else printf("open huffmanToBeTran.txt--file success!\n");
while(!feof(fp_text)){
ch = fgetc(fp_text);
//printf("%c ",ch);
i = find_letter(ch);
//printf("i = %d\n",i);
if(i!=0)
fprintf(fp_code,"%s ",qz[i].code);
}
//关闭文件
if(fclose(fp_code)){
printf("\a close HuffmanTreeCode.txt--file error!\n");
exit(0);
}//else printf("close HuffmanTreeCode.txt--file success !\n");
if(fclose(fp_text)){
printf("\a close huffmanToBeTran.txt--file error!\n");
exit(0);
}//else printf("close huffmanToBeTran.txt--file success !\n");
}
/*------查找字符*--------*/
int find_letter(char ch){
int low,high,i;
low = 1;high = t;
//二分查找
while(high - low >= 0){
i=(low+high)/2;
if(qz[i].letter == ch)
return i;
else if(qz[i].letter < ch){
low = i+1;
}
else
high = i-1;
}
return 0;
}
/*-------打印哈夫曼树的节点权值---------*/
void PrintHuffmanCode(){
if(ht[0].weight == 0){
printf("没初始化!\n");
Sleep(2000);//挂起一段时间
return;
}
if(qz[0].w == 0){
printf("检测到没有编码!!,请先编码\n");
Sleep(2000);
return;
}
int i=0;
char code[100];
FILE *fp_r,*fp_w;
if((fp_r=fopen("F:\\HuffmanTree\\HuffmanTreeCode.txt","r")) == NULL){
printf("\a open HuffmanTreeCode.txt--file error!\n");
exit(0);
}//else printf("open HuffmanTreeCode.txt success!\n");
if((fp_w=fopen("F:\\HuffmanTree\\CodePrint.txt","w")) == NULL){
printf("\a open CodePrint.txt--file error!\n");
exit(0);
}//else printf("open CodePrint.txt success!\n");
while(!feof(fp_r)){
fscanf(fp_r,"%s\n",code);
printf("%s ",code);
fprintf(fp_w,"%s",code);
i++;
if(i%5 == 0){
printf("\n");
fprintf(fp_w,"\n");
}
}
printf("打印成功啦…………!\n");
}
/*-------译码---------*/
void Decoding(){
if(ht[0].weight == 0){
printf("没初始化!\n");
Sleep(2000);//挂起一段时间
return;
}
if(qz[0].w == 0){
printf("检测到没有编码!!\n");
Sleep(2000);//挂起一段时间
return;
}
char code[100];
FILE *fp_r,*fp_w;
int i;
//打开CodeFile.txt文件,从中读取编码
if((fp_r=fopen("F:\\HuffmanTree\\CodePrint.txt","r")) == NULL){
printf("\a open HuffmanTreeCode.txt--file error!\n");
exit(0);
}//else printf("open HuffmanTreeCode.txt success!\n");
//打开TextFile.txt文件,存储翻译的内容
if((fp_w=fopen("F:\\HuffmanTree\\TextFile.txt","w")) == NULL){
printf("\a open TextFile.txt--file error!\n");
exit(0);
}//else printf("open TextFile.txt success!\n");
while(!feof(fp_r)){
fscanf(fp_r,"%s\n",code);
i = find_code(code);
if(i!=0)
fprintf(fp_w,"%c",qz[i].letter);
}
if(fclose(fp_r)){
printf("\a close HuffmanTreeCode.txt--file error!\n");
exit(0);
}//else printf("close HuffmanTreeCode.txt--file success !\n");
if(fclose(fp_w)){
printf("\a close TextFile.txt--file error!\n");
exit(0);
}//else printf("close TextFile.txt--file success !\n");
printf("恭喜你T^ _ ^T'译码'成功啦!\n");
}
/*-------查找编码------*/
int find_code(char s[]){
int i;
for(i=1;i<=t;i++){
if(strcmp(qz[i].code,s) == 0)
return i;
}
return 0;
}
/*-------打印树-----------*/
void TreePrinting(){
if(ht[0].weight == 0){
printf("没初始化!,请重试\n");
Sleep(2000);//挂起一段时间
return;
}
FILE *fp;
int i,r=t*2-1;
//打开文件
if((fp=fopen("F:\\HuffmanTree\\huffmanTreeprint.txt","w")) == NULL){
printf("\aopen HuffmanTreeCode.txt--file error !\n");
exit(0);
}
for(i=1;i<=r;i++){
if(ht[i].parent == 0)
break;
}
//printf("%d\n",ht[i].parent );
_print(fp,ht[i],0);
if(fclose(fp)){
printf("\aclose huffmanTreeprint.txt--file error!\n");
exit(0);
}
printf("打印成功啦!^*_*^\n");
}
/*-----哈夫曼树纵向显示并写入文件------*/
void _print(FILE *fp,HNode hft,int n){
if(hft.LChild == 0 && hft.RChild == 0){
for(int i=0;i<n;i++){
printf(" ");
fprintf(fp," ");
}
printf("%-6d\n",hft.weight);
fprintf(fp,"%-6d\n",hft.weight);
return ;
}
_print(fp,ht[hft.RChild],n+2);
for(int i=0;i<n;i++){
printf(" ");
fprintf(fp," ");
}
printf("%-6d\n",hft.weight);
fprintf(fp,"%-6d\n",hft.weight);
_print(fp,ht[hft.LChild],n+2);
}
/*------写入数据到文件(动态保存)-------*/
void Writedata_HT(int n){
FILE *fp_ht;
char ch;
int i,j;
char ch1;
int m = 2 * n - 1;
if((fp_ht = fopen ("F:\\HuffmanTree\\data.txt","w")) == NULL){
printf("open data.txt--file error !\n");
getchar();
exit(0);
}else{
fprintf(fp_ht , "动态建立的树为(其中生成树时生成的结点用“# ”表示):\n");
fprintf(fp_ht , "char weight parent lchild rchild\n");
for(i = 1; i <= m; i++){
fprintf(fp_ht , "%2c %5d %7d %7d %7d\n", HT[i].ch, HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
}
HC = (HuffmanCode)malloc((n+1) * sizeof(char*));
char *cd;
cd = (char *)malloc(n * sizeof(char));
cd[n-1] = '\0';//编码结束符
fprintf(fp_ht , "■其编码本内容为:\n");
fprintf(fp_ht , "■编码表为:\n");
int c,f,start;
for(i = 1 ; i <= n ; i++){//逐个字符求哈夫曼编码
start = n - 1;//编码结束符的位置
for(c = i ,f = HT[i].parent ; f != 0 ; c = f,f = HT[f].parent){
if(HT[f].lchild == c){
cd[--start] = '0';
}else{
cd[--start] = '1';
}
}
HC[i] = (char *)malloc((n - start)*sizeof(char)); //为第i个字符编码分配空间
strcpy(HC[i] , &cd[start]);//从cd复制编码(串)到HC
fprintf(fp_ht , "其结点为%c的编码为:",HT[i].ch);
fputs(HC[i] , fp_ht);
}
HuffmanCoding_print(n);
printf("\n将其保存至文件data.txt");
}
if(fp_ht != NULL){
printf("\n文件保存成功!!!");
}
fclose(fp_ht);
if((fp_ht = fopen("F:\\HuffmanTree\\data.txt","r")) == NULL){
printf("文件保存失败无法打开!!!");
getch();
exit(0);
}else{
ch1 = fgetc(fp_ht);
while(ch1 != EOF){
putchar(ch1);
ch1 = fgetc(fp_ht);
}
printf("\n");
}
fclose(fp_ht);
}
/*----------主函数------------*/
int main()
{
char chose;//主菜单的选择值
char sh , title;
int n,i,x,T;
system("CLS");//运行前清屏
system("color FD");//设置颜色
load();//等待函数
flag: //设置一个返回标记
system(“color F4”);
printf(“在编码前需要将哈夫曼初始化喔!!!”);
system("color FD");//把颜色改回来
Menu();//调用菜单,完成一系列工作
do{
printf("\a请选择如下的操作:");
fflush(stdin);
scanf("%c",&chose);
getchar();//除去回车
switch(chose){
case '1':Initialization();break; //初始化
case '2':Encoding();break; //对叶子节点进行编码
case '3':Decoding();break; //译码
case '4':PrintHuffmanCode();break; //打印编码
case '5':TreePrinting();break; //打印哈夫曼树
case '6':
do{
putTree_menu();
printf("请选择进行的二级目录操作: ");
scanf("%c",&sh);
printf("\n操作结果如下(T^__^T):\n");
switch(sh){
case '1':
printf("请输入要进行操作的数n(n>0):");
scanf("%d",&n);
HuffmanCoding(n);
break;
case '2':
HuffmanCoding_print(n);
break;
case '3':
Encoding_put(n);
break;
case '4':
Decoding_put(n);
break;
case '5':
Writedata_HT(n);
break;
case '0':
printf("完成任务(T_T)准备退出二级目录...\n");
Sleep(500);
printf("\t\n退出二级目录程序……谢谢使用!!!\n");
printf("\a请选择直接退出(1)或返回主目录(0):");
scanf("%d",&T);
if(T == 0){ system("CLS"); goto flag;}//运用goto语句返回主菜单
if(T == 1){ exit(-1); }
break;
}
}while(sh != 0 && scanf("%c",&sh) != EOF);
break;
case '7':
printf("马上为您退出了....!请稍后\n");//退出提醒
Sleep(500); //挂起0.5s
exit(0); //退出
break;
case '8':
system("Type F:\\HuffmanTree\\huffmanToBeTran.txt");//可以用文件指针追加填加一个能编辑文本的操做,用while(ch!=’#’)来填加字符
break;
default:printf("选错啦,再试试吧!\n");
}
}while(scanf("%c",&chose) != EOF);
system("PAUSE");
return 0;
}