数据结构——哈夫曼树及哈夫曼编码代码实现

#define MAXLEAFNUM 50 //最优二叉树中的最多叶子数目

typedef struct node{
    char ch;//结点表示的字符
    int weight;//权值
    int parent;//结点的父结点的下标,为0表示无父结点
    int lChild,rChild;//结点的左右孩子结点的下标,为0表示无孩子结点
}HuffmanTree[2*MAXLEAFNUM];

typedef char* HuffmanCode[MAXLEAFNUM + 1];

void select(HuffmanTree HT,int n,int &s1,int &s2)
{
    s1 = 1;
    s2 = 2;
    int nMinW = HT[1].weight;

    for(int  i = 1; i <= n;i++){
        if(HT[i].parent != 0){
            continue;
        }
        if(nMinW > HT[i].weight){
            nMinW = HT[i].weight;
            s1 = i;
        }
    }
    if(s1 != 1){
        nMinW = HT[1].weight;
    }else{
        nMinW = HT[2].weight;
    }
    for(int  i = 1; i <= n -1;i++){
        if(HT[i].parent != 0 || i == s1){
            continue;
        }

        if(nMinW > HT[i].weight){
            nMinW = HT[i].weight;
            s2 = i;
        }
    }
}

//创建哈夫曼树
void createHTree(HuffmanTree HT,char *c,int *w,int n)
{
    int i,s1,s2;
    if(n <= 1){
        return;
    }

    for(i = 1; i <= n;i++){//构造n棵只有根结点的树
        HT[i].ch = c[i - 1];
        HT[i].weight = w[i - 1];
        HT[i].parent = HT[i].lChild = HT[i].rChild = 0;
    }
    for(;i < 2 * n;i++){
        HT[i].parent = HT[i].lChild = HT[i].rChild = 0;
    }

    for(i = n + 1; i < 2 *n; i++){
        select(HT,i - 1,s1,s2);
        HT[s1].parent = i;
        HT[s2].parent = i;
        HT[i].lChild = s1;
        HT[i].rChild = s2;
        HT[i].weight = HT[s1].weight + HT[s2].weight;
    }
}

//根据给定的哈夫曼树,从每个叶子结点出发追溯到根,逆向找出最优二叉树中叶子结点的编码
//n个叶子结点在哈夫曼HT中的下标为1~n,第i(1<= i <= n)个叶子的编码存放在HC[i]中
void HuffmanCoding(HuffmanTree HT,HuffmanCode HC,int n)
{
    char *cd;
    int i,start,c,f;

    if(n <= 1){
        return;
    }
    cd = (char*)malloc( n * sizeof(char));//申请足够的空间存储编码
    cd[n -1] = '\0';//结尾符
    for(i = 1; i <= n;i++){
        start = n - 1;
        for(c = i,f = HT[i].parent;f != 0;c = f,f = HT[f].parent){//执行完一次后继续向上回溯结点
            if(HT[f].lChild == c){//如果当前结点与父结点的左节点相等,则对应字符编码为0,否则为1
                cd[start] = '0';
            }else{
                cd[start] = '1';
            }
            start--;
        }
        HC[i] = (char*)malloc((n - start) * sizeof(char));
        strcpy(HC[i],&cd[start]);
        free(cd);
    }
}

//利用最优二叉树译码
void Decoding(HuffmanTree HT,int n,char *buff)
{
    int p = 2 * n - 1;
    while (*buff) {
        if((*buff) == '0'){
            p = HT[p].lChild;
        }else{
            p = HT[p].rChild;
        }

        if(HT[p].lChild == 0 && HT[p].rChild == 0){
            cout << HT[p].ch << endl;
            p = 2 * n - 1;
        }
        buff++;
    }
}
发布了28 篇原创文章 · 获赞 4 · 访问量 7384

猜你喜欢

转载自blog.csdn.net/JuicyActiveGilbert/article/details/100672926