话不多说,上代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node
{
int bol,num;
char ch;
struct node* lchild;
struct node* rchild;
struct node* next;
}NODE;
typedef struct node* Node;
Node header=NULL;
int path[20],top=-1,k=0;
char B[200];
FILE* fp=NULL;
typedef struct ch
{
char chk;
int digi[100];
}CH;
CH dictnory[500];
char article()
{
gets(B);
int len = strlen(B);
int i,j,flag=0;
header = (Node)malloc(sizeof(NODE));
header->next = NULL;
Node p = header,q=header;
for (i = 0; i < len; i++)
{
p = header;
while (p->next!=NULL)
{
p = p->next;
if (p->ch == B[i])
{
p->num++;
flag = 1;
break;
}
}
if (flag != 1)
{
Node pr = NULL;
pr = (Node)malloc(sizeof(NODE));
pr->ch = B[i];
pr->num = 1;
q->next = pr;
q = pr;
pr->next = NULL;
}
flag = 0;
}
}
int lengh(Node header)
{
Node p=header;
int i=0;
while (p->next != NULL)
{
p=p->next;
i++;
}
return i;
}
void sort(Node header)
{
int i,j,len=lengh(header),flag=0;
Node p = header->next, pr = header;
for (i = 0;i<len; i++)
{
p = header->next;
pr = header;
for (j = 0; j < len - i; j++)
{
if (p->next != NULL)
{
if (p->num > p->next->num)
{
pr->next = p->next;
p->next = pr->next->next;
pr->next->next = p;
pr = pr->next;
flag = 1;
}
if (flag == 0)
{
p = p->next;
pr = pr->next;
}
flag = 0;
}
else break;
}
}
}
Node tree(Node header)
{
Node p = header->next,ph=header;
while (ph->next != NULL)
{
ph = ph->next;
ph->lchild = NULL;
ph->rchild = NULL;
}
while (p!=NULL)
{
Node p1;
p1 = (Node)malloc(sizeof(NODE));
p1->lchild = p;
p1->rchild = p->next;
p1->num = p->num + p->next->num;
p = p->next->next;
header->next = p;
p1->lchild->bol = 0;
p1->rchild->bol = 1;
p1->rchild->next = NULL;
p1->lchild->next = NULL;
ph = header;
while (ph->next != NULL && ph->next->num <= p1->num )
{
ph = ph->next;
}
p1->next = ph->next;
ph->next = p1;
}
return header->next;
}
Node stack(Node head)
{
if (head != NULL)
{
path[++top] = head->bol;
if (head->lchild == NULL && head->rchild == NULL)
{
printf("%c ", head->ch);
dictnory[k].chk = head->ch;
for (int i = 1; i <= top; i++)
{
dictnory[k].digi[i-1] =path[i];
printf("%d", path[i]);
dictnory[k].digi[i] = 2;
}
k++;
printf("\n");
}
stack(head->lchild);
stack(head->rchild);
--top;
}
}
void coding()
{
fp= fopen("D:/decode.txt", "wb");
printf("\n");
int i = 0,j=0,n=0;
while (B[i]!='\0')
{
while (1)
{
if (dictnory[j].chk == B[i])
{
while (dictnory[j].digi[n] != 2)
{
//fwrite(dictnory[j].digi, sizeof(int), 1, fp);
fprintf(fp, "%d", dictnory[j].digi[n]);
printf("%d", dictnory[j].digi[n]);
n++;
}
n = 0;
break;
}
j++;
}
j = 0;
i++;
}
fclose(fp);
}
void Read()
{
header = (Node)malloc(sizeof(NODE));
header->next = NULL;
Node ph = header;
Node p = NULL, pTemp = NULL;
pTemp = (Node)malloc(sizeof(NODE));
pTemp->next = NULL;
fp = fopen("D:/tree.txt", "rb");
fread(pTemp, sizeof(NODE), 1, fp);
while (feof(fp) == 0)
{
p = (Node)malloc(sizeof(NODE));
//strcpy(p->ch, pTemp->ch);
p->ch = pTemp->ch;
p->num=pTemp->num;
ph->next = p;
ph = p;
fread(pTemp, sizeof(NODE), 1, fp);
}
ph->next = NULL;
free(pTemp);
fclose(fp);
return;
}
void decoding()
{
char digital[300], i = 0;
Read();
Node pk = tree(header);
Node p = pk;
fp = fopen("D:/decode.txt", "r");
while (fscanf(fp, "%c", &digital[i]) != EOF)
{
printf("%c", digital[i]);
i++;
}
digital[i] = '\0';
printf("\n");
i = 0;
while (1)
{
while (1)
{
if (digital[i] == '0')
{
p = p->lchild;
}
else if (digital[i] == '1')
{
p = p->rchild;
}
i++;
if (p->lchild == NULL)
{
printf("%c", p->ch);
p = pk;
break;
}
}
if (digital[i] == '\0')
break;
}
}
int main()
{
int se;
printf("----提示: 要解码前必须先进行一次输入文章,以便建立储存哈夫曼树,并利用该哈夫曼树进行解码\n");
printf("按1压缩文章,按其他解码\0");
scanf("%d", &se);
setbuf(stdin, NULL);
if (se ==1)
{
printf("请输入字符串\n");
article();
sort(header);
save(header);
Node pk = tree(header);
stack(pk);
printf("对应编码码为:\n");
coding();
}
else
{
printf("文件的01序列对应解码为\n");
decoding();
}
}