数据结构:实现哈夫曼编码和解码

  1. 哈夫曼编码

任务:,树的每个结点代表一个集合元素。根据给定的若干权值来构造哈夫曼树,实现对应的哈夫曼编码以及译码。

功能要求:

  1. 按传输文本中字符的个数以及字符的频率来建立并输出哈夫曼树的存储结构;
  2. 将传输的文本转换成对应的哈夫曼编码01序列;
  3. 将哈夫曼编码01序列翻译成原来的文本字符。

界面要求:程序运行后,给出菜单项的内容和输入提示:

  1. 建立并输出哈夫曼树
  2. 将文本转换成01编码
  3. 将01编码翻译成文本
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define maxsize 100
    
    typedef struct N {
    	char Data='?';
    	int weight=0;
    	struct N* lchild;
    	struct N* rchild;
    	struct N* mother;
    	bool finish=0;
    	bool find = 0;
    	char code[maxsize] = {'\0'};
    	int len = 0;
    }Node;
    
    void change(Node* t, char str[]);
    void Gocode(Node* p);
    Node* Create(Node** p);
    void find(int* temp, Node** p,int num);
    void Porder(Node* t);
    void search(Node* t, char ch);
    void Getcode(Node* t);
    int main() {
    	Node* n[maxsize];
    	Node q;
    	char str[maxsize] ;
    	for (int i = 0; i < maxsize; i++) {
    		str[i] = '\0';
    	}
    	for (int i = 0; i < maxsize; i++) {
    		n[i] = (Node*)malloc(sizeof(Node));
    	}
    	Node *p=&q;
    	printf("1.建立并输出哈夫曼树");
    	printf("(设计并输出哈夫曼编码)\n");
    	printf("2.将文本转换成01编码\n");
    	printf("3.将01编码翻译成文本\n");
    	printf("0.退出\n");
    	while (1) {
    		int command;
    		printf("\n选择操作序号:\n");
    		scanf_s("%d", &command);
    		switch (command) {
    
    		case 1:
    			p = Create(n);
    			change(p, str);
    			Porder(p); break;
    		case 2:	Getcode(p); break;
    		case 3:	Gocode(p); break;
    		default:return 0;
    		}
    	}
    }
    
    Node* Create(Node** p) {
    	printf("输入元素个数:\n");
    	int num;
    	scanf_s("%d", &num);
    	printf("输入每个元素的权值和名字:\n");
    	for (int i = 0; i < num; i++) {
    		scanf_s("%d%c",&p[i]->weight, &p[i]->Data, 1);
    		p[i]->find = 0;
    		p[i]->lchild = NULL;
    		p[i]->rchild = NULL;
    		p[i]->len = 0;
    		for (int j = 0; j < maxsize; j++) {
    			p[i]->code[j] = '\0';
    		}
    	}	
    
    	Node* d,q;
    	d = &q;
    	if (num > 1) {
    		for (int i = 0; i < num - 1; i++) {
    			int temp[2] = { 0 };
    			find(temp, p,num);
    			d = (Node*)malloc(sizeof(Node));
    			d->lchild = p[temp[0]];
    			d->rchild = p[temp[1]];
    			d->find = 0;
    			d->weight = p[temp[0]]->weight + p[temp[1]]->weight;
    			d->len = 0;
    			for (int j = 0; j < maxsize; j++) {
    				d->code[j] = '\0';
    			}
    			p[temp[1]]->finish = 1;
    			p[temp[0]] = d;
    		}
    		return d;
    	}
    	else {
    		return p[0];
    	}
    }
    
    void find(int* temp, Node** p,int num) {
    	int min=10000,loc=0;
    	for (int i = 0; i < num; i++) {
    		if (p[i]->find==0) {
    			if (min > p[i]->weight) {
    				min = p[i]->weight;
    				loc = i;
    			}
    		}
    	}
    	temp[0] = loc;
    	p[loc]->find = 1;
    	loc = 0, min = 10000;
    	for (int i = 0; i < num; i++) {
    		if (!p[i]->find) {
    			if (min > p[i]->weight) {
    				min = p[i]->weight;
    				loc = i;
    			}
    		}
    	}
    	temp[1] = loc;
    	p[loc]->find = 1;
    }
    
    void Gocode(Node *p) {
    	Node* q = p;
    	Node* n = p;
    	char str[maxsize];
    	printf("\n输入编码:\n");
    	scanf_s("%s", str, maxsize);
    	int i = 0;
    	while (str[i] != '\0') {
    		q=p;
    		while (q) {
    			if (str[i] == '1') {
    				n = q;
    				q = q->lchild;
    				i++;
    			}
    			else {
    				n = q;
    				q = q->rchild;
    				i++;
    			}
    		}
    		i--;
    		printf("%c", n->Data);
    	}
    }
    void Porder(Node *t) {//递归先序
    	if (t)
    	{
    		printf("%c  ", t->Data);
    		Porder(t->lchild);
    		Porder(t->rchild);
    	}
    }
    
    void change(Node* t, char str[]) {
    	if (t) {
    		strcpy_s(t->code, str);
    		if (t->lchild) {
    			str[strlen(str)] = '1';
    			change(t->lchild, str);
    			str[strlen(str)-1] = '\0';
    		}
    		if (t->rchild) {
    			str[strlen(str)] = '0';
    			change(t->rchild, str);
    			str[strlen(str)-1] = '\0';
    		}
    	}
    }
    
    void search(Node* t, char ch) {
    	if (t)
    	{
    		if (t->Data == ch) {
    			for (int i = 0; i<strlen(t->code); i++) {
    				printf("%c", t->code[i]);
    			}
    			return;
    		}
    		search(t->lchild,ch);
    		search(t->rchild,ch);
    	}
    }
    
    void Getcode(Node* t) {
    	char str[maxsize];
    	printf("输入编码:\n");
    	scanf_s("%s", str, maxsize);
    	int i = 0;
    	while (str[i] != '\0') {
    		search(t, str[i]);
    		i++;
    	}
    }
    

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淬炼之火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值