- 哈夫曼编码
任务:,树的每个结点代表一个集合元素。根据给定的若干权值来构造哈夫曼树,实现对应的哈夫曼编码以及译码。
功能要求:
- 按传输文本中字符的个数以及字符的频率来建立并输出哈夫曼树的存储结构;
- 将传输的文本转换成对应的哈夫曼编码01序列;
- 将哈夫曼编码01序列翻译成原来的文本字符。
界面要求:程序运行后,给出菜单项的内容和输入提示:
- 建立并输出哈夫曼树
- 将文本转换成01编码
- 将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++; } }