杂谈:最近有点慵懒,不好不好。好几天都没写代码,原本准备上星期完结 树 这一章节的。现在 又耽误了。哎。要抓紧时间啊。
下面直接上代码:
可以到我的网盘下载源代码,或者 直接拷贝下面的源代码 运行
网盘地址:点击打开链接
// HuffmanTree.cpp : 定义控制台应用程序的入口点。 //哈弗曼编码,译码 #include "stdafx.h" #include <stdlib.h> #include <cstring> enum E_State { E_State_Error = 0, E_State_Ok = 1, }; struct HuffmanNode { int weight;//权值 int parent;//父亲节点 int leftChild;//左孩子 int rightChild;//右孩子 }; struct HuffmanCode { char srcCode;//原始码 char * dstCode;//赫夫曼编码 }; struct HuffmanTree { int len;//字符集的数量 HuffmanCode * codeArray;//编码数组 HuffmanNode * tree;//赫夫曼树.. }; void treeInit(HuffmanTree * tree){ tree->tree = NULL; tree->codeArray = NULL; tree->len = 0; } void treeDestory(HuffmanTree * tree){ free(tree->tree);//释放赫夫曼树 for (int i = 0; i < tree->len; i++)//释放编码 { free(tree->codeArray[i].dstCode); } free(tree->codeArray);//释放数组 treeInit(tree); } //从树里选择两个最小的节点(不包括已经有父亲的) void selectMin(HuffmanTree tree,int toIndex,int * minIndex1,int * minIndex2){ int times = 0; int min1,min2; for (int i = 0; i < toIndex; i++) { HuffmanNode node = tree.tree[i]; if (node.parent == 0) { if (times == 0)//第一次... { min1 = node.weight; *minIndex1 = i; } else if(times == 1)//第二次 { min2 = node.weight; *minIndex2 = i; } else if(min1 > node.weight || min2 > node.weight)//发现 有比 min1 ,min2 小的权值了. { /*min1 > min2 ? min1 = node.weight,*minIndex1 = i : min2 = node.weight,*minIndex2 = i;*/ if (min1 > min2) { min1 = node.weight; *minIndex1 = i; } else { min2 = node.weight; *minIndex2 = i; } } times++; } } } //根据 charSet 字符集合 和字符的权值数组 构建赫夫曼树,获取字符编码. E_State treeCreate(HuffmanTree * tree,char * charSet,int * weightArray){ int len = strlen(charSet); treeInit(tree); if (len > 0) { int num = 2 * len -1;//赫夫曼树的个数.. tree->tree = (HuffmanNode*)malloc(sizeof(HuffmanNode) * num); if (tree->tree != NULL) { //构建赫夫曼树 tree->codeArray = (HuffmanCode *)malloc(sizeof(HuffmanCode) * len); tree->len = len; for (int i = 0; i < len; i++)//初始化. { tree->tree[i].parent = 0; tree->tree[i].leftChild = 0; tree->tree[i].rightChild = 0; tree->tree[i].weight = weightArray[i]; //设置赫夫曼编码的源码 tree->codeArray[i].srcCode = charSet[i]; } for (int i = len; i < num; i++) { int minIndex1,minIndex2;//最小权值的两个节点的索引 selectMin(*tree,i,&minIndex1,&minIndex2);//获得索引 tree->tree[minIndex1].parent = i; tree->tree[minIndex2].parent = i; tree->tree[i].leftChild = minIndex1; tree->tree[i].rightChild = minIndex2; tree->tree[i].weight = tree->tree[minIndex1].weight + tree->tree[minIndex2].weight; tree->tree[i].parent = 0; } //构建赫夫曼编码 char * tempCode = (char *) malloc(sizeof(char) * len); tempCode[len-1] = '\0'; for (int i = 0; i < len; i++) { HuffmanNode node = tree->tree[i]; char * pCode = tempCode+ len-2; int childIndex = i; int times = 0; while (node.parent != 0) { HuffmanNode parent = tree->tree[node.parent]; parent.leftChild == childIndex ? *pCode-- = '0' : *pCode-- = '1'; childIndex = node.parent; node = parent; times++; } tree->codeArray[i].dstCode = (char *) malloc(sizeof(char) * times+1);// 写成times会报错 strcpy(tree->codeArray[i].dstCode,pCode+1); } free(tempCode); return E_State_Ok; } } return E_State_Error; } //将 string 转换成 赫夫曼编码 char * findCode(HuffmanTree tree,char data){ for (int i = 0; i < tree.len; i++) { if (tree.codeArray[i].srcCode == data) { return tree.codeArray[i].dstCode; } } return NULL; } void encode(HuffmanTree tree,char * string,char * code){ char * pCode = code; for (;*string != '\0'; string++) { char * dstCode = findCode(tree,*string); if (dstCode != NULL) { for (;*dstCode != '\0'; dstCode++) { *pCode++ = *dstCode; } } else { printf("------存在非法字符-----------\n"); return; } } *pCode = '\0'; } //将string 解码 void decode(HuffmanTree tree,char * string,char * code){ int total = 0; while (*string != '\0') { int treeNum = 2*tree.len - 1; //由 结构可知:赫夫曼树的最后一个节点为根节点 HuffmanNode child = tree.tree[treeNum -1]; int childIndex; while (child.leftChild != 0 || child.rightChild != 0) { if (*string == '0')//左子树 { childIndex = child.leftChild; child = tree.tree[childIndex]; } else if(*string == '1')//右子树. { childIndex = child.rightChild; child = tree.tree[childIndex]; } string++; } code[total++] = tree.codeArray[childIndex].srcCode; } code[total] = '\0'; } void treeTraverse(HuffmanTree tree){ for (int i = 0; i < tree.len; i++) { HuffmanCode code = tree.codeArray[i]; printf("%c 的 编码值为:%s\n",code.srcCode,code.dstCode); } } int _tmain(int argc, _TCHAR* argv[]) { HuffmanTree tree; int weightArray[] = {18,12,5,10,15,8,13,19}; char * string = "abcdefgh"; treeCreate(&tree,string,weightArray); printf("%s 的 赫夫曼编码 如下:\n",string); treeTraverse(tree); char * encodeBefore = "abcdefghghfdab";//编码前 源码 char afterCode[1000];//编码后 encode(tree,encodeBefore,afterCode); printf("%s 编码后:%s\n",encodeBefore,afterCode); char src[1000]; decode(tree,afterCode,src); printf("%s 解码后:%s\n",afterCode,src); treeDestory(&tree); return 0; }运行截图:
原文地址:http://blog.csdn.net/fuming0210sc/article/details/44779571