【数据结构】Huffman树

参照书上写的Huffman树的代码 结构用的是线性存储的结构 不是二叉链表 里面要用到查找最小和第二小 理论上锦标赛法比较好 但是实现好麻烦啊 考虑到数据量不是很大 就直接用比较笨的先找最小 去掉最小再找第二小的方法了。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
    unsigned int weight;
    unsigned int parent, lchild, rchild;
}HTNode, *HuffmanTree;

typedef char ** HuffmanCode;

int Select(HuffmanTree HT, int n, int &s1, int &s2)
{
    if(n <= 1) return 1;
    else
    {
        int i;
        s1 = 0; s2 = 0;
        for(i = 1; i <= n; i++)
        {
            if(s1 == 0 && HT[i].parent == 0)
            {
                s1 = i;
            }
            else if(HT[i].parent == 0 && HT[i].weight < HT[s1].weight && s1 != 0)
            {
                s1 = i;
            }
        }
        for(i = 1; i <= n; i++)
        {
            if(i == s1)
            {
                continue;
            }
            else if(s2 == 0 && HT[i].parent == 0)
            {
                s2 = i;
            }
            else if(HT[i].parent == 0 && HT[i].weight < HT[s2].weight && s2 != 0)
            {
                s2 = i;
            }
        }
    }
    return 0;
}
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int * w, int n)
{
    if(n <= 1) return;
    int m = 2 * n - 1;
    HuffmanTree p;
    int i;
    HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));
    for(p = HT, i = 1; i <= n; i++, p++, w++)  //初始化
    {
        p->weight = *w; p->parent = 0; p->rchild = 0; p->lchild = 0;
    }
    for( ; i <= m; i++, p++)
    {
        p->weight = 0; p->parent = 0; p->rchild = 0; p->lchild = 0;
    }

    for(i = n + 1; i <= m; i++) //建Huffman树
    {
        int s1, s2;
        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;
        HT[i].parent = 0; //不加这句会出错
    }

    HC = (HuffmanCode)malloc((n + 1) * sizeof(char *));
    char * cd = (char *)malloc(n * sizeof(char));
    cd[n - 1] = '\0';
    for(i = 1; i <= n; i++)
    {
        int start = n - 1;
        int c, f;
        for(c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
        {
            if(HT[f].lchild == c) cd[--start] = '0';
            else{ cd[--start] = '1';}
        }
        HC[i] = (char *)malloc((n - start) * sizeof(char));
        strcpy(HC[i], &cd[start]);
    }
    free(cd);
}

int main()
{
    int N = 10; //一共10个权值
    int w[10] = {1,2,3,4,5,6,7,8,9,0};
    HuffmanTree HT;
    HuffmanCode HC;
    HuffmanCoding(HT, HC,  w, N);

    int i, j;
    for(i = 1; i <= N; i++)
    {
        printf("%d: ", i);
        for(j = 0; HC[i][j] != '\0'; j++)
        {
            printf("%c", HC[i][j]);
        }
        printf("\n");
    }

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值