#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;
}