数据结构哈夫曼树的构造以及哈夫曼编码与解码实验

#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]);
		}
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值