huffman
#include "stdlib.h" #include "string.h" #include "stdio.h" typedef struct FreTab_s FreTab; struct FreTab_s { int weight; char c; }; typedef struct Node_s Node; struct Node_s { int weight; char c; Node* pNext; Node* pLeft; Node* pRight; }; typedef struct SearchTab_s SearchTab; struct SearchTab_s { char code; char validBit; char orign; }; FreTab g_freTab[] = {{2,'b'},{1,'a'},{3,'c'},{4,'d'},{5,'e'}}; SearchTab g_searchTab[5] = {0}; Node* g_pRoot = NULL; char reverseCode(char code, int len) { unsigned char a = code; a = ((a&0xAA)>>1) | ((a&0x55)<<1); a = ((a&0xCC)>>2) | ((a&0x33)<<2); a = ((a&0xF0)>>4) | ((a&0x0F)<<4); a>>=(8-len); return a; } Node* AllocNode(int weight,char c) { Node* pNode = NULL; pNode = (Node*)malloc(sizeof(Node)); memset(pNode,0,sizeof(Node)); pNode->weight = weight; pNode->c = c; return pNode; } void insertNode(Node* pNode) { Node* pPreNode = NULL; Node* pCurNode = NULL; if(NULL == g_pRoot->pNext) { g_pRoot->pNext = pNode; } else { pPreNode = g_pRoot; pCurNode = g_pRoot->pNext; while(pCurNode) { if(pNode->weight <= pCurNode->weight) { break; } pPreNode = pCurNode; pCurNode = pCurNode->pNext; } pNode->pNext = pCurNode; pPreNode->pNext = pNode; } return; } void initList() { Node* pTemp = NULL; g_pRoot = AllocNode(0,0); for(int i=0;i<sizeof(g_freTab)/sizeof(FreTab);i++) { pTemp = AllocNode(g_freTab[i].weight,g_freTab[i].c); insertNode(pTemp); } return; } void constructHuffmanTree() { Node* pCurNode = NULL; Node* pNextNode = NULL; Node* pTemp = NULL; pCurNode = g_pRoot->pNext; if(NULL == pCurNode) { return; } pNextNode = pCurNode->pNext; if(NULL == pNextNode) { return; } pTemp = AllocNode(pCurNode->weight+pNextNode->weight,0); pTemp->pLeft = pCurNode; pTemp->pRight = pNextNode; g_pRoot->pNext = pNextNode->pNext; insertNode(pTemp); constructHuffmanTree(); } void constructSearchTable(Node* pNode,int code,int validBit) { int index = 0; if((NULL==pNode->pLeft)&&(NULL==pNode->pRight)) { index = pNode->c - 'a'; g_searchTab[index].code = reverseCode(code,validBit); g_searchTab[index].validBit = validBit; g_searchTab[index].orign = pNode->c; } return; } void PreorderTraversal(Node* pNode,int encode, int flag, int validBit) { if(NULL == pNode) { return; } if (-1 != flag) { encode= encode<<1; encode+=flag; validBit++; constructSearchTable(pNode,encode,validBit); } printf("%d--%d\n",encode,validBit); PreorderTraversal(pNode->pLeft,encode,0,validBit); PreorderTraversal(pNode->pRight,encode,1,validBit); } //获取low--high范围的编码信息 int getPartCode(int low, int high, char code) { int num; int bitnum; int mask = 0;; num = high; bitnum = high-low; while(num--) { mask <<= 1; if(bitnum) { mask++; bitnum--; } } return code&mask; } void getCodeInfo(char c,char* code,char* validBit) { int index = 0; index = c - 'a'; *code = g_searchTab[index].code; *validBit = g_searchTab[index].validBit; } void encodeString(char* pBuf, char* pStr) { int index = 0; int nextFlag = 1; char code = 0; char validBit = 0; char temp = 0; char lowerCode = 0; char bufInnerPos = 0; char bufOuterPos = 0; while(pStr[index]) { if (nextFlag) { getCodeInfo(pStr[index],&code,&validBit); } if(8-bufInnerPos >= validBit) { code<<=bufInnerPos; temp|=code; bufInnerPos = (bufInnerPos+validBit)%8; if(0==bufInnerPos) { pBuf[bufOuterPos++] = temp; temp = 0; } nextFlag = 1; index++; } else { lowerCode = getPartCode(0,8-bufInnerPos,code); lowerCode<<=bufInnerPos; temp|=lowerCode; pBuf[bufOuterPos++] = temp; temp=0; code = getPartCode(8-bufInnerPos,validBit,code); validBit -=(8-bufInnerPos); bufInnerPos = 0; nextFlag = 0; } } pBuf[bufOuterPos]=temp; return; } int searchTree(Node** ppNode, int flag, char*c) { Node* pNode = NULL; if(flag) { pNode = (*ppNode)->pRight; } else { pNode = (*ppNode)->pLeft; } if((NULL==pNode->pLeft)&&(NULL==pNode->pRight)) { *c = pNode->c; *ppNode = g_pRoot->pNext; return 1; } *ppNode = pNode; return 0; } void decodeString(char* pBuf, char* pStr, int len) { char temp = 0; char temp1 = 0; char flag = 0; char c = 0; Node* pNode = g_pRoot->pNext; for(int i=0;i<len;i++) { temp = pBuf[i/8]; temp1 = getPartCode(i%8,(i%8)+1,temp); if(temp&temp1) { flag=1; } else { flag=0; } if(searchTree(&pNode,flag,&c)) { *pStr++ = c; } } } int main() { initList(); constructHuffmanTree(); PreorderTraversal(g_pRoot->pNext,0,-1,0); char buf[2] ={0}; encodeString(buf,"abcdecc"); char str[8]={0}; decodeString(buf,str,16); return 0; }