源代码——哈夫曼树的编码解码

来源:互联网 发布:淘宝店招商 编辑:程序博客网 时间:2024/05/01 18:50


哈夫曼树

#define  _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <string.h>#include <malloc.h>//哈夫曼编码分析://问题是:给一个输入的字符串进行哈夫曼编码//前提:需要知道这个字符串字符种类及其频度(权)//那么需要函数统计字符串的字符种类及其频度//FREQ *getAlphaFreq(char *str, int *count, int *alpha)(字符串,字符种类,每种字符个数)//其二:上述函数获得了频度,还需要在哈夫曼树中的基础上一次获得频度最小的// int findMinFreqAlpha()//其三:初始化哈弗曼树//其四:创建哈夫曼表//其五:销毁哈弗曼树//其六:打印哈弗曼树//其七:获得哈夫曼编码//前提:获得哈夫曼 0 1 序列//其八:哈夫曼解码//定义一个字母及其频度结构体struct FREQ{unsigned char alpha;int freq;};typedef struct FREQ FREQ;//定义一个哈夫曼表 结构体struct HUFFMAN_TABLE{unsigned char alpha;int freq;int lChild;int rChild;unsigned char accessFlag;char *hufCode;};typedef struct HUFFMAN_TABLE HUFFMAN_TABLE;#define NOT_FOUND0#define FOUND1FREQ *getAlphaFreq(char *str, int *alphaKind, int *alpha);int findMinFreqAlpha(HUFFMAN_TABLE *hufTab, int account);HUFFMAN_TABLE *initHufTab(FREQ *freq, int alphaCount);HUFFMAN_TABLE *createHufTab(FREQ *freq, int alphaCount);void destoryHufTab(HUFFMAN_TABLE *huf, int alphaCount);void showHufTree(HUFFMAN_TABLE *huf, int alphaCount);void makeHufmanCode(HUFFMAN_TABLE *huf, int root, int codeIndex, char *code);int getHufStringLen(HUFFMAN_TABLE *huf, int alphaCount);char *coddingString(HUFFMAN_TABLE *huf, int alphaCount, int *alphaHufIndex, char *string);char *decoddingString(HUFFMAN_TABLE *huf, int alphaCount, char *string);char *decoddingString(HUFFMAN_TABLE *huf, int alphaCount, char *string){int i = 0;int root = 2 * (alphaCount - 1);char *result;int t = 0;int strLen = getHufStringLen(huf, alphaCount);result = (char *)malloc(sizeof(char)* huf[root].freq + 1);while(i <= strLen){if (-1 != huf[root].lChild){root = string[i++] == '1' ? huf[root].lChild : huf[root].rChild;}else{result[t++] = huf[root].alpha;root = 2 * (alphaCount - 1);}}result[t] = 0;return result;}char *coddingString(HUFFMAN_TABLE *huf, int alphaCount, int *alphaHufIndex, char *string){char *codestr;int i;codestr = (char *)calloc(sizeof(char), getHufStringLen(huf, alphaCount) + 1);for (i = 0; string[i]; i++){strcat(codestr, huf[alphaHufIndex[string[i]]].hufCode);}return codestr;}int getHufStringLen(HUFFMAN_TABLE *huf, int alphaCount){int sum = 0;int i;for (i = 0; i < alphaCount; i++){sum += huf[i].freq * strlen(huf[i].hufCode);}return sum;}void makeHufmanCode(HUFFMAN_TABLE *huf, int root, int codeIndex, char *code){if (-1 == huf[root].lChild){code[codeIndex] = 0;strcpy(huf[root].hufCode, code);}else{code[codeIndex] = '1';makeHufmanCode(huf, huf[root].lChild, codeIndex + 1, code);code[codeIndex] = '0';makeHufmanCode(huf, huf[root].rChild, codeIndex + 1, code);}}void showHufTree(HUFFMAN_TABLE *huf, int alphaCount){int i;printf("下标 字符    频度     左孩子 右孩子  Flag哈弗曼编码\n");for (i = 0; i < 2 * alphaCount - 1; i++){printf("%4d\t%4c\t%4d\t%6d\t%6d\t%4d\t%s\n",i,huf[i].alpha,huf[i].freq,huf[i].lChild,huf[i].rChild,huf[i].accessFlag,huf[i].hufCode);}}void destoryHufTab(HUFFMAN_TABLE *huf, int alphaCount){int i;for (i = 0; i < alphaCount; i++){free(huf[i].hufCode);}//free(huf);}HUFFMAN_TABLE *createHufTab(FREQ *freq, int alphaCount){HUFFMAN_TABLE *huf;int i;int lChild, rChild;huf = initHufTab(freq, alphaCount);for (i = 0; i < alphaCount; i++){lChild = findMinFreqAlpha(huf, alphaCount + i);rChild = findMinFreqAlpha(huf, alphaCount + i);huf[alphaCount + i].alpha = (unsigned char)NULL;huf[alphaCount + i].freq = huf[lChild].freq + huf[rChild].freq;huf[alphaCount + i].lChild = lChild;huf[alphaCount + i].rChild = rChild;huf[alphaCount + i].accessFlag = NOT_FOUND;huf[alphaCount + i].hufCode = NULL;}return huf;}HUFFMAN_TABLE *initHufTab(FREQ *freq, int alphaCount){HUFFMAN_TABLE *huf;int i;huf = (HUFFMAN_TABLE *)malloc(sizeof(HUFFMAN_TABLE)*(2 * alphaCount - 1));for (i = 0; i < alphaCount; i++){huf[i].alpha = freq[i].alpha;huf[i].freq = freq[i].freq;huf[i].lChild = huf[i].rChild = -1;huf[i].accessFlag = NOT_FOUND;huf[i].hufCode = (char *)calloc(sizeof(char), alphaCount);}return huf;}int findMinFreqAlpha(HUFFMAN_TABLE *hufTab, int account){int minIndex = -1;int i;for (i = 0; i < account; i++){if (hufTab[i].accessFlag == NOT_FOUND &&(minIndex == -1 || hufTab[i].freq < hufTab[minIndex].freq))minIndex = i;}hufTab[minIndex].accessFlag = FOUND;return minIndex;}FREQ *getAlphaFreq(char *str, int *count, int *alpha){FREQ *p = NULL; //获得的字符串频度信息保存在该结构体int cnt = 0;  //字符串种类int i, j;if (NULL == str){printf("error: str is null\n");return NULL;}for (i = 0; str[i]; i++){alpha[str[i]]++;//不同位置的相同字符是数组的同一个元素 ++}for (i = 0; i < 256; i++){if (alpha[i]){cnt++;}}p = (FREQ *)malloc(sizeof(FREQ)*cnt);for (i = j = 0; i < 256 && j < cnt; i++){if (alpha[i]){p[j].alpha = i;//i是对应字符的ascii码,此处会以char 类型解释p[j].freq = alpha[i];alpha[i] = j++;}}*count = cnt;return p;}void main(){char str[1024];FREQ *freqPoint;int alphaCount;int i;HUFFMAN_TABLE *huf;char *code;int alphaHufIndex[256] = { 0 };char *coString;char *deString;printf("请输入一个字符串:\n");gets(str);printf("源字符串是:\n");puts(str);freqPoint = getAlphaFreq(str, &alphaCount, alphaHufIndex);for (i = 0; i < alphaCount; i++){printf("%c:%d\n", freqPoint[i].alpha, freqPoint[i].freq);}huf = createHufTab(freqPoint, alphaCount);code = (char *)malloc(sizeof(char *)* alphaCount);makeHufmanCode(huf, 2 * (alphaCount - 1), 0, code);showHufTree(huf, alphaCount);coString = coddingString(huf, alphaCount, alphaHufIndex, str);printf("哈弗曼编码之后得到:\n");puts(coString);printf("解码之后得到:\n");deString = decoddingString(huf, alphaCount, coString);puts(deString);free(deString);free(coString);free(code);destoryHufTab(huf, alphaCount);free(freqPoint);system("pause");}

给出一幅图共度代码的时候参考:


0 0
原创粉丝点击