中易网

哈夫曼树,我这样构造对不对,如果对,还有另外的一种形式吗?

答案:2  悬赏:50  
解决时间 2021-02-17 12:41
哈夫曼树,我这样构造对不对,如果对,还有另外的一种形式吗?
最佳答案
八个权值是 5 29 7 8 14 23 3 11

(1) 从小到大排序 3 5 7 8 11 14 23 29 (这是有序序列)
(2) 每次提取最小的两个结点,取结点3和结点5,组成新结点N8,其权值=3+5=8,
    取数值较小的结点作为左分支,结点3作为左分支,而结点5就作为右分支.
(3) 将新结点N8放入有序序列,保持从小到大排序:
    7 8 N8 11 14 23 29  [注意,新结点N8排在原结点8的后面]
(4) 重复步骤(2),提取最小的两个结点,结点7与结点8组成新结点N15,其权值=7+8=15,
    结点7的数值较小,将结点7作为左分支,结点8就作为右分支.
(5) 将新结点N15放入有序序列,保持从小到大排序:
    N8 11 14 N15 23 29
(6) 重复步骤(2),提取最小的两个结点,N8与结点11组成新结点N19,其权值=8+11=19,
    N8的数值较小,作为左分支,结点11就作为右分支.
(7) 将新结点N19放入有序序列,保持从小到大排序:
    14 N15 N19 23 29
(8) 重复步骤(2),提取最小的两个结点,结点14与N15组成新结点N29,其权值=14+15=29,
    结点14的数值较小,作为左分支,N15就作为右分支.
(9) 将新结点N29放入有序序列,保持从小到大排序:
    N19 23 29 N29  [注意,新结点N29排在原结点29的后面]
(10)重复步骤(2),提取最小的两个结点,N19与结点23组成新结点N42,其权值=19+23=42,
    N19的数值较小,作为左分支,结点23就作为右分支.
(11)将新结点N42放入有序序列,保持从小到大排序:
    29 N29 N42
(12)重复步骤(2),提取最小的两个结点,结点29与N29组成新结点N58,其权值=29+29=58,
    结点29与N29的数值相同,将原结点29作为左分支,N29就作为右分支.
(13)将新结点N58放入有序序列,保持从小到大排序:
    N42 N58
(14)重复步骤(2),提取剩下的两个结点,N42与N58组成新结点N100,其权值=42+58=100,
    数值较小的N42作为左分支,N58就作为右分支.
    最后得到"哈夫曼树":

              N100
           /       
          N42      N58
         /        /  
        N19  23   29  N29
       /            /  
      N8  11       14   N15
     /                /  
    3    5            7    8

带权路径长度(WPL):
根结点N100到结点29的路径长度是2,结点29的带权路径长度是29*2
根结点N100到结点23的路径长度是2,结点23的带权路径长度是23*2
根结点N100到结点14的路径长度是3,结点14的带权路径长度是14*3
根结点N100到结点11的路径长度是3,结点11的带权路径长度是11*3
根结点N100到结点8的路径长度是4,结点8的带权路径长度是8*4
根结点N100到结点7的路径长度是4,结点7的带权路径长度是7*4
根结点N100到结点5的路径长度是4,结点5的带权路径长度是5*4
根结点N100到结点3的路径长度是4,结点3的带权路径长度是3*4
所以,哈夫曼树的带权路径长度(WPL)等于
29*2 + 23*2 + 14*3 + 11*3 + 8*4 + 7*4 + 5*4 + 3*4 = 271

哈夫曼编码:
规定哈夫曼树的左分支代表0,右分支代表1.
从根结点N100到结点29,先经历右分支,再经历左分支,结点29的编码就是10
从根结点N100到结点23,先经历左分支,再经历右分支,结点23的编码就是01
从根结点N100到结点14,经历两次右分支,再经历左分支,结点14的编码就是110
如此类推,得出所有结点的"哈夫曼编码":
权值29: 10
权值23: 01
权值14: 110
权值11: 001
权值8 : 1111
权值7 : 1110
权值5 : 0001
权值3 : 0000


//C语言测试程序:

//输入叶子结点的总个数: 8
//连续输入8个权值: 5 29 7 8 14 23 3 11
//Weight=5   Code=0001
//Weight=29  Code=10
//Weight=7   Code=1110
//Weight=8   Code=1111
//Weight=14  Code=110
//Weight=23  Code=01
//Weight=3   Code=0000
//Weight=11  Code=001
//huffman's WPL is: 271

#include 
#include 

#define MaxValue 10000  //初始设定的权值最大值
#define MaxBit 10       //初始设定的最大编码位数
#define MaxN 10         //初始设定的最大结点个数
struct HuffNode         //哈夫曼树的结点结构
{
    int weight;//权值
    int flag;//标记
    int parent;//双亲结点下标
    int leftChild;//左孩子下标
    int rightChild;//右孩子下标
};
struct Code//存放哈夫曼编码的数据元素结构
{
    int bit[MaxBit];//数组
    int start;//编码的起始下标
    int weight;//字符的权值
};

//建立叶结点个数为n权值为weight的哈夫曼树huffTree
void Huffman(int weight[], int n, struct HuffNode huffTree[])
{
    int i,j, m1, m2, x1, x2;
    //哈夫曼树huffTree初始化。n个叶结点的哈夫曼树共有2n-1个结点
    for (i = 0; i<2 * n - 1; i++)
    {
        if (i        {
            huffTree[i].weight = weight[i];
        }
        else
        {
            huffTree[i].weight = 0;
        }
        huffTree[i].parent = 0;
        huffTree[i].flag = 0;
        huffTree[i].leftChild = -1;
        huffTree[i].rightChild = -1;
    }
    //构造哈夫曼树huffTree的n-1个非叶结点
    for (i = 0; i    {
        m1 = m2 = MaxValue;//Maxvalue=10000;(就是一个相当大的数)
        x1 = x2 = 0;//x1、x2是用来保存最小的两个值在数组对应的下标

        for (j = 0; j        {
            if (huffTree[j].weight            {
                m2 = m1;
                x2 = x1;
                m1 = huffTree[j].weight;
                x1 = j;
            }
            else if(huffTree[j].weight            {
                m2 = huffTree[j].weight;
                x2 = j;
            }
        }
        //将找出的两棵权值最小的子树合并为一棵子树
        huffTree[x1].parent = n + i;
        huffTree[x2].parent = n + i;
        huffTree[x1].flag = 1;
        huffTree[x2].flag = 1;
        huffTree[n + i].weight = huffTree[x1].weight + huffTree[x2].weight;
        huffTree[n + i].leftChild = x1;
        huffTree[n + i].rightChild = x2;
    }
}
//由n个结点的哈夫曼树huffTree构造哈夫曼编码huffCode
void HuffmanCode(struct HuffNode huffTree[], int n, struct Code huffCode[])
{
    struct Code *cd=(struct Code *)malloc(sizeof(struct Code));
    int child, parent;
    int i,j;
    //求n个叶结点的哈夫曼编码
    for (i = 0; i    {
        cd->start = 0;  //从0开始计数
        cd->weight = huffTree[i].weight; //取得编码对应权值的字符
        child = i;
        parent = huffTree[child].parent;
        //由叶结点向上直到根结点
        while (parent != 0)
        {
            if (huffTree[parent].leftChild == child)
            {
                cd->bit[cd->start] = 0; //左孩子结点编码0
            }
            else
            {
                cd->bit[cd->start] = 1; //右孩子结点编码1
            }
            cd->start++; //编码自增
            child = parent;
            parent = huffTree[child].parent;
        }
        //重新修改编码,从根结点开始计数
        for (j = cd->start - 1; j >= 0; j--)
        {
            huffCode[i].bit[cd->start - j - 1] = cd->bit[j];
        }
        huffCode[i].start = cd->start;
        huffCode[i].weight = cd->weight;//保存编码对应的权值
    }
}
int main()
{
    int i, j;
    int m = 0;
    int n = 0;
    int weight[20];

    printf("输入叶子结点的总个数: ");
    scanf("%d",&n);
    printf("连续输入%d个权值: ",n);
    for(i=0;i    {
        scanf("%d",&weight[i]);
    }
struct HuffNode *myHuffTree=(struct HuffNode *)malloc((2*n-1)*sizeof(struct HuffNode));
struct Code *myHuffCode=(struct Code *)malloc(n*sizeof(struct Code));
    if (n>MaxN)
    {
        printf("
定义的n越界,修改MaxN!
");
        exit(0);
    }
    Huffman(weight, n, myHuffTree);
    HuffmanCode(myHuffTree, n, myHuffCode);
    //输出每个叶结点的哈夫曼编码
    for (i = 0; i    {
        printf("Weight=%-4dCode=",myHuffCode[i].weight);
        for (j = 0; j        {
            printf("%d",myHuffCode[i].bit[j]);
        }        m = m + myHuffCode[i].weight*myHuffCode[i].start;

        printf("
");
    }
    printf("huffman's WPL is: %d
",m);

getchar();

    return 0;
}
全部回答
对,还有很多种,不过能写出来一种就行了
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
三国演义动画版张飞抢亲是第几级
求百度云或360云资源链接
神舟九号运载火箭是几级火箭
贷款期限2+1年 什么意思
想找前女友吃个饭可以吗
茶陵县洣江汽车贸易有限公司地址在什么地方,
什么的胜地?什么的南沙?什么的岛屿?
比尔盖茨为什么辞职
侦察兵如何为炮兵指引目标的?!
We have been long back at school three wee
vixx中的主唱是谁,在歌曲error
现货黄金语音直播室
“我的拍摄作品”用英文怎么说
芦花鸡和普通家鸡在外观和使用价值上有什么区
不小心摸到男友捷豹了。。。
推荐资讯
雅澜瑜伽会馆地址好找么,我有些事要过去
经不起诱惑还是买了那个梵婕缇眼膜,不知道去
二补村桥这个地址在什么地方,我要处理点事
刚新组装的电脑,按开机键没反应!!!!!!
什么才是真正的三防手机
如果上半年申请语文教师资格证证,没通过,下
急求!安卓手机突然一根手指滑动不了屏幕了,
红楼梦 原著
jm珍珠防晒喷雾要卸妆吗
刘文西画一副,此画在家中多年一直不懂,最近
有首歌开头我曾经的蘑菇头然 偶尔喝喝小酒借
洪祥菜馆(泉胜物流店)这个地址在什么地方,我
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?