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

 

posted @ 2014-02-11 22:01  平凡之路  阅读(236)  评论(0)    收藏  举报