哈夫曼编码

来源:互联网 发布:java学生信息管理系统 编辑:程序博客网 时间:2024/06/02 13:05
#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct{int weight;int parent;int left;int right;}HuffmanTree;typedef char * HuffmanCode;/************************************************************************  函数名称:SelectNode  函数功能:得到前面i-1个结点中权重最小的两个结点,bt1, bt2函数参数:ht是指向哈夫曼树的指针,n是创建树的叶结点的数量,w用来传入n个叶结点的权值 函数返回:无************************************************************************/ void SelectNode(HuffmanTree *ht, int n, int * bt1, int * bt2){int i;HuffmanTree *ht1, *ht2, *t;ht1 = ht2 = NULL;for (i = 1; i <= n; i++){if (!ht[i].parent){if (ht1 == NULL)//结点指针1为空{ht1 = ht + i;continue;}if (ht2 == NULL){ht2 = ht + i;if (ht1->weight > ht2->weight){t = ht1;ht1 = ht2;ht2 = t;}continue;}if (ht1 && ht2){if (ht[i].weight <= ht1->weight){ht2 = ht1;ht1 = ht + i;}else if (ht[i].weight > ht1->weight){ht2 = ht + i;}}//if (ht1 && ht2)}//if (!ht[i].parent)}//for (i = 1; i <= n; i++)if (ht1 > ht2){*bt2 = ht1 - ht;*bt1 = ht2 - ht;}else{*bt1 = ht1- ht;*bt2 = ht2 - ht;}}/************************************************************************  函数名称:CreateTree  函数功能:创建哈夫曼树函数参数:ht是指向哈夫曼树的指针,n是创建树的叶结点的数量,w用来传入n个叶结点的权值 函数返回:无************************************************************************/ void CreateTree(HuffmanTree *ht, int n, int *w){int i, m = 2 * n - 1;//总的结点数int bt1, bt2;//二叉树结点序号if (n <= 1) return;//如果只有一个结点,无法创建for (i = 1; i <= n; i++){ht[i].weight = w[i-1];ht[i].parent = 0;ht[i].left = 0;ht[i].right = 0;}for ( i = n+1; i <= m; i++){ht[i].weight = 0;ht[i].parent = 0;ht[i].left = 0;ht[i].right = 0;}for (i = n+1; i <= m; i++){SelectNode(ht, i-1, &bt1, &bt2);//调用函数得到前面i-1个结点中权重最小的两个结点,bt1, bt2ht[bt1].parent = i;ht[bt2].parent = i;ht[i].left = bt1;ht[i].right = bt2;ht[i].weight = ht[bt1].weight + ht[bt2].weight;}}/************************************************************************  函数名称:HuffmanCoding  函数功能:为哈夫曼树生成每个字符的哈夫曼编码函数参数:ht是指向哈夫曼树的指针,n是创建树的叶结点的数量,hc用来返回生成的  哈夫曼编码字符串首地址,供调用程序使用函数返回:无************************************************************************/ void HuffmanCoding(HuffmanTree *ht, int n, HuffmanCode *hc){char *cd;int start, i;int current, parent;cd = (char *)malloc(sizeof(char)*n);cd[n-1] = '\0';//for (i = 1; i<= n; i++){start = n - 1;current = i;parent = ht[current].parent;while (parent){if (current == ht[current].left)cd[--start] = '0';elsecd[--start] = '1';current = parent;parent = ht[parent].parent;}hc[i-1] = (char *)malloc(sizeof(char)*(n - start));strcpy(hc[i-1], &cd[start]);}free(cd);}/************************************************************************  函数名称:Encode  函数功能:根据哈夫曼编码将字符串进行编码,得到编码后的字符串,将一个字符串转换为哈夫曼编码函数参数:hc是指向HuffmanCoding函数生成的哈夫曼编码表;  alphabet指向哈夫曼编码的字符集(对哪些字符进行了编码);  str指向需要进行编码的字符串;  code用来返回编码后的结果函数返回:code用来返回编码后的结果************************************************************************/ void Encode(HuffmanCode *hc, char *alphabet, char *str, char *code){int len = 0, i = 0, j;code[0] ='\0';while (str[i]){j = 0;while (alphabet[j] != str[i])j++;strcpy(code + len, hc[j]);len = len + strlen(hc[j]);i++;}code[len] = '\0';}/************************************************************************  函数名称:Decode  函数功能:将一个哈夫曼编码组成的字符串转换为明文字符串函数参数:ht指向通过CreatTree函数生成的哈夫曼树;  m为叶结点的数量;  code是哈夫曼编码字符串(通过Encode函数生成的编码字符串);  alphabet指向哈夫曼编码的字符集(对哪些字符进行了编码);  decode用来返回解码后的结果函数返回:decode用来返回解码后的结果************************************************************************/ void Decode(HuffmanTree *ht, int m, char *code, char *alphabet, char *decode){int position = 0, i, j = 0;m = 2 * m - 1;while (code[position]){for (i = m; ht[i].left && ht[i].right; position++){if (code[position] == '0')i = ht[i].left;elsei = ht[i].right;}decode[j] = alphabet[i - 1];j++;}decode[j] = '\0';}/************************************************************************  函数名称:main  函数功能:测试程序函数参数:函数返回:0表示成功************************************************************************/ int main(){int i, n = 4, m;char test[] = "DBDBDABDCDADBDADBDADDACDBDBD";char code[100], code1[100];//保存编码和解码的字符串char alphabet[] = {'A', 'B', 'C', 'D'};int w[] = {5, 7, 2, 13};HuffmanTree *ht;HuffmanCode *hc;m = 2 * n -1;ht = (HuffmanTree *)malloc((m+1) * sizeof(HuffmanTree));if (!ht){printf("内存分配失败!\n");exit(0);}hc = (HuffmanCode *)malloc(n * sizeof(char *));if (!hc){printf("内存分配失败!");exit(0);}CreateTree(ht, n, w);HuffmanCoding(ht, n, hc);for (i = 1; i <= n; i++)printf("字母:%c, 权重:%d, 编码为 %s\n", alphabet[i-1], ht[i].weight, hc[i-1]);Encode(hc, alphabet, test, code);printf("\n字符串:\n%s\n转换后为:\n%s\n", test, code);Decode(ht, n, code, alphabet, code1);printf("\n编码:\n%s\n转换后为:\n%s\n", code, code1);getchar();getchar();return 0;}

0 0
原创粉丝点击