#include<stdio.h>
#include<stdlib.h>
char mins[30];
//哈夫曼树结构体集合
typedef struct Node{
int weight;
int parent,lchild,rchild;
}NODE,*PNODE;
typedef struct HuffTree{
PNODE pbase;
int len;
}HUFFTREE,*PHUFFTREE;
//哈夫曼编码结构体集合
typedef struct HuffNode{//每一个字母所对应的哈夫曼编码
char letter;
int code[10];
int num;//每个字母对应的哈夫曼编码的有效长度
}HUFFNODE,*PHUFFNODE;
typedef struct HuffCode{//哈夫曼编码数组
HUFFNODE huffNodes[30];
int len;
}HUFFCODE,*PHUFFCODE;
typedef struct Linknode{
int bit;
Linknode* next;
}LINKNODE,*PLINKNODE;
typedef struct Linklist{
PLINKNODE head;
}LINKLIST,*PLINKLIST;
void init_linklist(PLINKLIST);
void deleteFirstElement_linklist(PLINKLIST);
void init_HuffTree(PHUFFTREE,int);
void show_HuffTree(HUFFTREE);
void creat_HuffTree(PHUFFTREE,int []);
void findFirstminandSecondminweight_HuffTree(PHUFFTREE);
void makehuffmancode_HuffTree(HUFFTREE,int,PHUFFNODE);
void translate_article(HUFFCODE,PLINKLIST);
void end_function(HUFFCODE,PLINKLIST);
int main(void){
int a[30];
char c[26];
printf("请输入电文:");
scanf("%s",&mins);
printf("您输入的电文是:%s",mins);
printf("\n");
int asc=97;
int num=0;
int l=0;
while(asc<=122){
int k=0;
for(int i=0;i<30;i++){
if(mins[i]==asc){
k++;
mins[i]==0;
}
}
if(k!=0){
a[l]=k;
c[l]=asc;
num++;
l++;
}
asc++;
}
int f=0;
while(a[f]!=0&&c[f]!=0){
printf("%c------->%d",c[f],a[f]);
printf("\n");
f++;
}
PHUFFTREE phuffTree=(PHUFFTREE)malloc(sizeof(HUFFTREE));
init_HuffTree(phuffTree,num);
creat_HuffTree(phuffTree,a);
findFirstminandSecondminweight_HuffTree(phuffTree);
show_HuffTree(*phuffTree);
PHUFFCODE huffcode = (PHUFFCODE)malloc(sizeof(HUFFCODE));
for(int p=0;p<(phuffTree->len+1)/2;p++) {
PHUFFNODE huffnode=(PHUFFNODE)malloc(sizeof(HUFFNODE));
makehuffmancode_HuffTree(*phuffTree,p,huffnode);
huffnode->letter=c[p];
huffcode->huffNodes[p]=*huffnode;
huffcode->len++;
}
for(int i=0;i<(phuffTree->len+1)/2;i++){
printf("%c------->",huffcode->huffNodes[i].letter);
for(int j=0;j<10;j++){
if(huffcode->huffNodes[i].code[j]!=-1){
printf("%d",huffcode->huffNodes[i].code[j]);
}
else{
continue;
}
}
printf(" ");
printf("该字母的编码的有效长度为:%d",huffcode->huffNodes[i].num);
printf("\n");
}
printf("\n");
PLINKLIST linklist=(PLINKLIST)malloc(sizeof(LINKNODE));
init_linklist(linklist);
translate_article(*huffcode,linklist);
end_function(*huffcode,linklist);
}
void init_linklist(PLINKLIST p){//初始化链表
p->head=(PLINKNODE)malloc(sizeof(LINKNODE));
p->head->next=NULL;
}
void deleteFirstElement_linklist(PLINKLIST p){
PLINKNODE need=p->head->next;
p->head->next=p->head->next->next;
free(need);
}
void init_HuffTree(PHUFFTREE p,int n){
int k=2*n-1;
p->len=k;
p->pbase=(PNODE)malloc(sizeof(NODE)*k);
for(int i=0;i<k;i++){
p->pbase[i].weight=-1;
p->pbase[i].parent=-1;
p->pbase[i].lchild=-1;
p->pbase[i].rchild=-1;
}
}
void show_HuffTree(HUFFTREE h){
printf("******************The Hufftree table********************\n");
printf("******** weight parent lchild rchild********\n");
for(int i=0;i<h.len;i++){
printf("******** %2d %2d %2d %2d ********\n",h.pbase[i].weight,h.pbase[i].parent,h.pbase[i].lchild,h.pbase[i].rchild);
}
printf("********************************************************\n");
}
void creat_HuffTree(PHUFFTREE p, int matic[]){
for(int i=0;i<(p->len+1)/2;i++){
p->pbase[i].weight=matic[i];
}
}
void findFirstminandSecondminweight_HuffTree(PHUFFTREE p){
int firstmin;
int secondmin;
int len=(p->len+1)/2;//并不是对所有的weight,而是weight不是-1的排队
while(len!=p->len){
for(int i=0;i<len;i++){
if(p->pbase[i].parent!=-1){//如果parent不是-1,也不进行排队
continue;
}
else{
firstmin=i;
}
}
for(int i=0;i<len;i++){
if(p->pbase[i].parent!=-1){
continue;
}
if(p->pbase[i].weight<p->pbase[firstmin].weight){
firstmin=i;
}
}
for(int i=0;i<len;i++){
if(p->pbase[i].parent!=-1){
continue;
}
else if(i==firstmin){
continue;
}
else{
secondmin=i;
}
}
for(int i=0;i<len;i++){
if(p->pbase[i].parent!=-1){
continue;
}
if(i==firstmin){
continue;
}
if(p->pbase[i].weight<p->pbase[secondmin].weight){
secondmin=i;
}
}
p->pbase[len].weight=p->pbase[firstmin].weight+p->pbase[secondmin].weight;
p->pbase[len].lchild=firstmin;
p->pbase[len].rchild=secondmin;
p->pbase[firstmin].parent=len;
p->pbase[secondmin].parent=len;
len++;
}
}
void makehuffmancode_HuffTree(HUFFTREE h,int n,PHUFFNODE p){
int pos;
int parent;
int a[10];
p->num=0;//把长度初始化为0
for(int j=0;j<10;j++){
a[j]=-1;
}
pos=n;
int i=0;
parent=h.pbase[pos].parent;
while(parent!=-1){
if(pos==h.pbase[parent].lchild){
a[9-i]=0;
}
else{
a[9-i]=1;
}
pos=parent;
parent=h.pbase[pos].parent;
i=i+1;
}
for(int j=0;j<10;j++){
if(a[j]!=-1){
p->code[j]=a[j];
p->num++;
}
else{
p->code[j]=a[j];
}
}
}
void translate_article(HUFFCODE h,PLINKLIST p){
char codes[20],a;
int codesint[100];
int i=0;
printf("请输入二进制串:");
while((a=getchar())!='#') {
codes[i++]=a;
}
codes[i]='\0';
printf("\n");
for(int j=0;j<i;j++){
if(codes[j]=='0'){
codesint[j]=0;
continue;
}
if(codes[j]=='1'){
codesint[j]=1;
continue;
}
}
printf("您输入的二进制串为:");
PLINKNODE tail=p->head;
for(int j=1;j<i;j++){
PLINKNODE bitnode=(PLINKNODE)malloc(sizeof(LINKNODE));
bitnode->bit=codesint[j];
bitnode->next=NULL;
tail->next=bitnode;
tail=bitnode;
}
PLINKNODE print=p->head->next;
while(print!=NULL){
printf("%d",print->bit);
print=print->next;
}
printf("\n");
}
void end_function(HUFFCODE h,PLINKLIST p){
int flag=1;
int y=0;
char ends[30];
while(p->head->next!=NULL){
int i=0;
int count=0;
//int flag=1;//打一个布尔标记
PLINKNODE compare = p->head->next;
int mark;
for(int j=0;j<h.huffNodes[i].num;j++){
//int mark=0;
if(compare!=NULL&&compare->bit==h.huffNodes[i].code[10-h.huffNodes[i].num+j]){
compare=compare->next;
count++;
mark=1;
}
else{//表示和该字母的哈夫曼编码没有匹配上,那么要换下一个字母比对,从头开始。
i=i+1;
j=-1;//重新开始循环判断
compare = p->head->next;
count=0;
mark=0;
//flag=0;
}
}
//程序能执行到这里表示已经找到了一个字母得以匹配
//如果mark=1表示找到匹配字符结束
//如果mark=0表示没有找到匹配的字符
if(mark==1){//表示找到了
ends[y]=h.huffNodes[i].letter;
y++;
//printf("%c",h.huffNodes[i].letter);
for(int k=0;k<h.huffNodes[i].num;k++){
deleteFirstElement_linklist(p);
}
}
if(mark==0&&i==h.len){
flag=0;
printf("\n");
printf("编码格式错误,翻译失败!");
break;
}
}
if(flag==1){
printf("翻译的结果为:");
for(int g=0;g<y;g++){
printf("%c",ends[g]);
}
}
}
数据结构哈夫曼树的构造以及哈夫曼编码与解码实验
最新推荐文章于 2024-01-21 11:51:15 发布