幻想森林

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2765|回复: 2

[通用编程] 哈夫曼樹構造哈夫曼編碼

[复制链接]

313

主题

1574

帖子

1万

积分

⑧专业

*永恒国度*

积分
14145
QQ
发表于 2008-5-4 17:01:29 | 显示全部楼层 |阅读模式
程序如下:
  1. #include<stdio.h>
  2. #define MaxSize 50
  3. typedef struct
  4. {
  5.     char data; //結點值
  6.     int weight;//權重
  7.     int parent;//父結點
  8.     int left;  //左結點
  9.     int right; //右結點
  10. }huffnode;
  11. typedef struct
  12. {
  13.     char cd[MaxSize];
  14.     int start;
  15. }huffcode;
  16. void creahuffman(huffnode ht[],int n) // 構造哈夫曼樹
  17. {
  18.     int i,k,l,r,m1,m2;
  19.     for(i=0;i<2*n-1;i++)
  20.         ht[i].parent=ht[i].left=ht[i].right=0;
  21.     for(i=n;i<2*n-1;i++)              
  22.     {
  23.         m1=m2=32767;                 //l,r為最小權重的兩個結點位置
  24.         l=r=0;
  25.         for(k=0;k<i-1;k++)
  26.             if(ht[k].parent==0)
  27.                 if(ht[k].weight<m1)
  28.                 {
  29.                     m2=m1;r=l;
  30.                     m1=ht[k].weight;
  31.                     l=k;
  32.                 }
  33.                 else if(ht[k].weight<m2)
  34.                 {
  35.                     m2=ht[k].weight;
  36.                     r=k;
  37.                 }
  38.                 ht[l].parent=i;ht[r].parent=i;
  39.                 ht[i].weight=ht[l].weight+ht[r].weight;
  40.                 ht[i].left=l;ht[i].right=r;
  41.     }
  42. }
  43. void creahfcode(huffnode ht[],huffcode hcd[],int n) //求哈夫曼編碼
  44. {
  45.     int i,f,c;
  46.     huffcode d;
  47.     for(i=0;i<n;i++)
  48.     {
  49.         d.start=n+1;c=i;
  50.         f=ht[i].parent;
  51.         while(f!=0)
  52.         {
  53.             if(ht[f].left==c)
  54.                 d.cd[--d.start]='0';
  55.             else
  56.                 d.cd[--d.start]='1';
  57.             c=f;f=ht[f].parent;
  58.         }
  59.         hcd[i]=d;
  60.     }
  61. }
  62. void disphuffman(huffnode ht[],huffcode hcd[],int n) //輸出哈夫曼編碼
  63. {
  64.     int i,k;
  65.     printf("輸出哈夫曼編碼:\n");
  66.     for(i=0;i<n;i++)
  67.     {
  68.         printf("%c:",ht[i].data);
  69.         for(k=hcd[i].start;k<=n;k++)
  70.             printf("%c",hcd[i].cd[k]);
  71.         printf("\n");
  72.     }
  73. }
  74. void main()
  75. {
  76.     int n=6;
  77.     huffnode ht[2*MaxSize];
  78.     huffcode hcd[MaxSize];
  79.     ht[0].data='a'; ht[1].data='b';
  80.     ht[2].data='c'; ht[3].data='d';
  81.     ht[4].data='e'; ht[5].data='f';
  82.     ht[0].weight=10; ht[1].weight=2;
  83.     ht[2].weight=6;  ht[3].weight=4;
  84.     ht[4].weight=3;  ht[5].weight=1;
  85.     creahuffman(ht,n);
  86.     creahfcode(ht,hcd,n);
  87.     disphuffman(ht,hcd,n);
  88. }
复制代码

牠是結點在左子樹上編碼就為0,在右子樹上就為1。
大蝦們能詳細解釋下嗎?我實在是不太理解是怎麼實現的。
[img][/img] http://shop33698673.taobao.com被别人嫉妒,证明你优秀,嫉妒别人说明你无能
回复

使用道具 举报

1

主题

19

帖子

656

积分

⑤进阶

大猫

积分
656
QQ
发表于 2008-5-28 18:47:03 | 显示全部楼层
呃……其实左子树用1右子树用0也可以倒是……就是编码和它相反,平均码长还是一样的……

举个例子吧:
比如有a,b,c,d,e共5个字符,每个字符在某篇文章中,且文章中只含这几个字符(这文章估计很2 - -|)它们出现的概率(即权值)分别为0.2,0.05,0.4,0.25,0.1,现在需要对它们进行2进制编码,原则是出现概率大的编码长度要短,且各个编码不能出现歧义(歧义即为某一个编码的前n个字符为另一个编码)。这个问题思路其实是这样的:

先选两个权值最小的,即b和e,将它们作为一棵树的两个结点,它们的父结点定义为f,那f的权值应该是0.05 + 0.1 = 0.15
再从a,c,d,f中选两个权值最小的(注意现在f是一棵树,其余都只有结点),选出来f和a,再次把二者合成为一颗新树,定义f与a的父结点为g,g的权值为0.15 + 0.2 = 0.35
再从c,d,g中选两个权值最小的……
……
最后会形成一种最优二叉树的结构……然后分别对每个结点的左右分支进行0,1编码,最后就可以得到从root到任意结点的编码

以上是程序的一般思路……

程序主要实现还是在选择2个最小权值子树和将二者合成为一个新子树上……啊,突然有点头晕 ……
回复 支持 反对

使用道具 举报

313

主题

1574

帖子

1万

积分

⑧专业

*永恒国度*

积分
14145
QQ
 楼主| 发表于 2008-5-31 11:33:14 | 显示全部楼层
我差不多忘记了,才有人回答, 以后复习时再看
[img][/img] http://shop33698673.taobao.com被别人嫉妒,证明你优秀,嫉妒别人说明你无能
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|幻想森林

GMT+8, 2024-4-30 03:55 , Processed in 0.020517 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表