c语言实现霍夫曼树

c语言实现霍夫曼树


#include<stdio.h>
#include<string.h>
#include<stdlib.h>

 
typedef struct {
	char value;
	int weight;
	int parent,lchild,rchild;	
	char cd[20];
}HTNode;
 
HTNode SSS[26];
int sum=0;

void HTcd(char str[]){
 	int m;
	char tempcd[20];
	char voidone[20]="";
	int t;
 	int sub;
 	int weights[26];
	char values[26];
 	int i,j;
 	int flag=0;
 	int min1s1,min2s2;
 	int counter;
 	HTNode min1,min2;
 	
 	
	for (i=0;str[i]!='\0';i++){
		flag=0;
  		for (j=0;j<=i;j++){
   			if (str[i]==values[j]){
    			weights[j]++;
    			flag=1;
   			}
  		}
  		if (flag==0){
    		weights[sum]=1;
    		values[sum]=str[i];
     		sum++;
  		}	
 	}
 	for(i=0;i<sum;i++){
 		printf("%c的权为%d\n",values[i],weights[i]);
	}
	m=(2*sum)-1;
 	for(i=0;i<sum;i++){
	 	SSS[i].value=values[i];
	 	SSS[i].weight=weights[i];
	 	SSS[i].parent=0;
	 	SSS[i].lchild=0;
	 	SSS[i].rchild=0;
	}
	for(;i<=m;i++){
	 	SSS[i].value=0;
	 	SSS[i].weight=0;
	 	SSS[i].parent=0;
	 	SSS[i].lchild=0;
	 	SSS[i].rchild=0;
	}
	for(i=0;i<m;i++){
		sub+=SSS[i].weight;
	}
	counter=sum;
	for(i=sum;i<m;i++){
		min1s1=i-1;
		min2s2=i-1;
		min1.weight=sub+1;
		min2.weight=sub+1;
		for(j=0;j<counter;j++){
			if(SSS[j].parent!=0) continue;
			else if(min1.weight>=SSS[j].weight){
			min1.weight=SSS[j].weight;
			min1.value=SSS[j].value;
			min1s1=j;
			} 
		}
		for(j=0;j<counter;j++){
			if(SSS[j].parent!=0) continue;
			else if (min2.weight>=SSS[j].weight&&SSS[j].value!=min1.value){
				min2.weight=SSS[j].weight;
				min2.value=SSS[j].value;
				min2s2=j;
			}	
		}	
		counter++;
		SSS[min1s1].parent=i;
		SSS[min2s2].parent=i;
		SSS[i].lchild=min1s1;
		SSS[i].rchild=min2s2;
		SSS[i].weight=SSS[min1s1].weight+SSS[min2s2].weight;
	}


	printf("建好后的树为:\n");
	for(j=0;j<sum;j++){
		i=j;
		t=0;
		for(;SSS[i].parent!=0;) {
			if(SSS[(SSS[i].parent)].lchild==i)  tempcd[t]='0';
			else if(SSS[(SSS[i].parent)].rchild==i) tempcd[t]='1'; 
			i=SSS[i].parent;
			t++;
		}
		strrev(tempcd);
		strcpy(SSS[j].cd,tempcd);
		strcpy(tempcd,voidone);
	}
	for(j=0;j<m;j++){
		printf("第%d个字符%c的权为%d,父为%d,左子为%d,右子为%d,霍夫曼码为%s\n",j,SSS[j].value,SSS[j].weight,SSS[j].parent,SSS[j].lchild,SSS[j].rchild,SSS[j].cd);
	}
	printf("源码编码后为:");
	for(i=0;str[i]!='\0';i++){
		for(j=0;j<sum;j++){
			if(SSS[j].value==str[i]) printf("%s ",SSS[j].cd);
		}
	}
	printf("\n");
}

void HTtra(char str[]){
	printf("密码翻译后为:");
 	int i,j=0;
	i=(2*sum)-2;
 	while (str[j]!='2'){
 		if(str[j]=='0') i=SSS[i].lchild;
 		else if(str[j]=='1') i=SSS[i].rchild;	
 		if(SSS[i].lchild==0&&SSS[i].rchild==0) {
			printf("%c",SSS[i].value);i=(2*sum)-2;
		}
 		j++;
	 }	 
}
 
int main(){
 	int process=0;
 	char str[200];
 	char decode[200];
	FILE *fp;  
	int i,j;
	char acc[20];
	
	if((fp=fopen("D:\\SourceFile.txt","r"))==NULL) printf("打开文件失败,不能读取源码\n");
	else{
		fscanf(fp,"%s",&str);
		rewind(fp);
		fclose(fp);
		HTcd(str);
		process=1;
	}

	if((fp=fopen("D:\\Code.txt","w"))==NULL) printf("打开文件失败,不能输出编码字典\n");
	else if(process==1){
		printf("打开文件成功\n");
		for(i=0;i<sum;i++) {
		fprintf(fp,"%c的编码为",SSS[i].value);
			fprintf(fp,"%s\n",SSS[i].cd);
		}
		rewind(fp);
		fclose(fp);
	}
			
	if((fp=fopen("D:\\ResultFile.txt","w"))==NULL) printf("打开文件失败,不能输出编码\n");
	else if(process==1){
		fprintf(fp,"源字符串的编码为");
		for(i=0;str[i]!='\0';i++){
			for(j=0;j<sum;j++){
				if(SSS[j].value==str[i])
					fprintf(fp,"%s",SSS[j].cd);
			}
		}
		fprintf(fp,"2");
		rewind(fp);
		fclose(fp);
		printf("编码已写好\n");
	}			
			
	printf("请输入要进行译码的文件的路径\n");
	scanf("%s",&acc);				
	if((fp=fopen(acc,"r"))==NULL) printf("打开文件失败,不能读取译码");
	else if(process==1){
		fscanf(fp,"%s",&decode);
		rewind(fp);
		fclose(fp);
		HTtra(decode);
	}		
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言实现霍夫曼树的完整代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NODE_NUM 1000 struct huffman_node { char ch; int freq; int left_child; int right_child; }; void swap(struct huffman_node *a, struct huffman_node *b) { struct huffman_node temp = *a; *a = *b; *b = temp; } void sort(struct huffman_node *node_list, int node_num) { for (int i = 0; i < node_num; i++) { for (int j = i + 1; j < node_num; j++) { if (node_list[i].freq > node_list[j].freq) { swap(&node_list[i], &node_list[j]); } } } } void build_huffman_tree(struct huffman_node *node_list, int node_num) { int parent = node_num; while (1) { sort(node_list, node_num); if (node_num == 1) { break; } struct huffman_node new_node; new_node.ch = '\0'; new_node.freq = node_list[0].freq + node_list[1].freq; new_node.left_child = node_list[0].freq < node_list[1].freq ? 0 : 1; new_node.right_child = node_list[0].freq >= node_list[1].freq ? 0 : 1; node_list[0] = new_node; node_list[1] = node_list[node_num - 1]; node_num--; } } void print_huffman_code(struct huffman_node *node_list, int node_index, char *code, int depth) { if (node_list[node_index].ch != '\0') { printf("%c: %s\n", node_list[node_index].ch, code); } else { code[depth] = '0'; print_huffman_code(node_list, node_list[node_index].left_child, code, depth + 1); code[depth] = '1'; print_huffman_code(node_list, node_list[node_index].right_child, code, depth + 1); } } void huffman_encoding(char *text) { int freq_table[256] = {0}; int len = strlen(text); for (int i = 0; i < len; i++) { freq_table[text[i]]++; } int node_num = 0; struct huffman_node node_list[MAX_NODE_NUM]; for (int i = 0; i < 256; i++) { if (freq_table[i] > 0) { struct huffman_node node; node.ch = i; node.freq = freq_table[i]; node.left_child = -1; node.right_child = -1; node_list[node_num++] = node; } } build_huffman_tree(node_list, node_num); char code[256] = ""; print_huffman_code(node_list, node_num - 1, code, 0); } int main() { char text[] = "hello, world"; huffman_encoding(text); return 0; } ``` 代码中包含了几个函数: - `swap`:交换两个结构体的值 - `sort`:根据结点频率排序 - `build_huffman_tree`:构建霍夫曼树 - `print_huffman_code`:打印霍夫曼编码 - `huffman_encoding`:对给定文本进行霍夫曼编码 在 `main` 函数中,我们指定了要编码的文本为 `"hello, world"`,并调用了 `huffman_encoding` 函数进行编码。编码的结果将会在控制台中输出。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值