哈弗曼编码与解码

  今天介绍一下哈弗曼编码与解码。
什么是哈夫曼编码?怎么进行哈弗曼编码?以及进行哈夫曼编码之后怎么进行解码工作呢?表急,接下来我会简单介绍一下。
===========================================以下来自我老师的PPT课件====================================================
哈夫曼编码能够使通常的数据传输数量减少到最小。这个编码的发明和这个算法一样十分引人入胜。他的算法也广泛应用于传真机,图象压缩和计算机安全领域。
      哈夫曼树:带权路径长度最小的二叉树,亦称最优二叉树。
  哈夫曼树的特点: 
      1、权值越大的叶子结点越靠近根结点,而权值越小的叶子结点越远离根结点。(构造哈夫曼树的核心思想)
      2、只有度为0(叶子结点)和度为2(分支结点)的结点,不存在度为1的结点。
      3、n个叶结点的哈夫曼树的结点总数为2n-1个。
      4、哈夫曼树不唯一,但WPL唯一。
   ===============================让yogurt偷个懒,嘿嘿嘿========================================
 
 
至于哈夫曼树的构造方法:就是把结点的权值按照从小往大依次向上进行合并,如图:(yogurt的字有点丑~~~~(>_<)~~~~大家将就看看就好哈)

编码方法:就是从根结点开始,根结点的左孩子编码为0,右孩子编码为1,再把左孩子结点当做根结点(右孩子结点也当做根结点),继续编码,直到编码到叶子结点为止。
从根节点直到目标结点,一路上经过的编码就是最终的编码啦!
大家可以直接在代码中看到方法的体现,接下来,上代码:
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 typedef char** HC;
  5 
  6 typedef struct Node
  7 {
  8     int weight;
  9     char character;
 10     struct Node* parent,* lchild,* rchild;
 11 }node,*huffmantree;
 12 
 13 huffmantree CreateHuffmantree(node * H, int n);
 14 HC code(huffmantree HT, int n);
 15 char decode(huffmantree HT, char * c);
 16 
 17 void main()
 18 {
 19     int w[7] = { 3,4,1,4,2,6,8 };
 20     char v[7] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
 21     int n = 7,i,j;
 22     node H[13];//保存每一个结点,前7位是叶节点(即规定权值),后6位是分支结点
 23     for (i = 0, j = 0; i < 13; i++, j++)
 24     {
 25         if (i < 7)
 26         {
 27             H[i].weight = w[j];
 28             H[i].character = v[j];
 29         }
 30         else
 31         {
 32             H[i].weight = 0;
 33             H[i].character = ' ';
 34         }
 35         H[i].parent = 0;
 36         H[i].lchild = 0;
 37         H[i].rchild = 0;
 38     }//哈弗曼树初始化
 39 
 40     huffmantree HT = (huffmantree)malloc(13 * sizeof(node));//分配空间
 41     HT = CreateHuffmantree(H, 13);//创建哈夫曼树
 42     HC hc = (HC)malloc(7 * sizeof(char*));
 43     hc = code(HT,7);//编码
 44     
 45     //验证
 46     printf("哈夫曼编码已完成。\n请输入验证字符:");
 47     char ch = getchar();
 48     for (i = 0; i < 7;i++)  //遍历到输入字符的编码指针处
 49     {
 50         if (HT[i].character == ch)
 51             break;
 52     }  //求第i个字符的编码,在hc[i]处
 53     printf("%c的哈夫曼编码为:", ch);
 54     puts(hc[i]);
 55     
 56     //解码
 57     char m=decode(HT, hc[i]);
 58     printf("解码为:");
 59     printf("%c", m);
 60 
 61     getchar();
 62     return;
 63 }
 64 
 65 huffmantree CreateHuffmantree(node * H, int n)
 66 {
 67     int i = 7, j; 
 68     while (i < n)  //完善H的分支结点,从H[7]-H[n-1]
 69     {
 70         int min1 = 100, min2 = 100, x = 0, y = 0; //x、y分别记录第二小和最小的元素位置
 71         for (j = 0; j <n; j++)  
 72         {
 73             if(H[j].weight>0&&H[j].parent==0)  //从已经有值且没有parent指针的结点中找
 74             {
 75                 if (H[j].weight <min2)
 76                 {
 77                     if (H[j].weight < min1)
 78                     {
 79                         min2 = min1;
 80                         min1 =H[j].weight;
 81                         x =y;
 82                         y = j;
 83                     }
 84                     else
 85                     {
 86                         min2 = H[j].weight;
 87                         x = j;
 88                     }
 89                 }
 90             }
 91         }  //找到最小的两个元素的位置
 92         H[i].weight =H[x].weight + H[y].weight;
 93         H[i].lchild = &H[x];
 94         H[i].rchild = &H[y];
 95         H[x].parent = &H[i];
 96         H[y].parent = &H[i];
 97         
 98         i++;
 99     }
100     return H;
101 }
102 
103 HC code(huffmantree HT, int n)
104 {
105     int i,j;
106     node * c,* f;
107     HC hc = (HC)malloc(7 * sizeof(char*));
108     for (i = 0; i < n; i++)  //为n个字符编码,目前为第i个字符编码,存放在哈弗曼树的第i个结点上
109     {
110         j = 6;  //每次进来j都要重新变成一次6
111         hc[i] = (char*)malloc(7 * sizeof(char));
112         char a[7]; //编码的临时存放地
113         a[6] = '\0';
114         for (c = &HT[i], f = c->parent; f != 0; c = f, f = f->parent)
115         {
116             if ((f->lchild) == c)
117                 a[--j] = '0';
118             else
119                 a[--j] = '1';
120         }
121         strcpy(hc[i], &a[j]);
122     }
123     return hc;
124 }
125 
126 char decode(huffmantree HT, char * c)  //c是哈夫曼编码,末尾是'\0'
127 {
128     //找到哈弗曼树的根结点
129     int i;
130     for (i = 0; HT[i].parent != 0; i++);
131     
132     //从根结点开始往下走
133     node *n = &HT[i];
134     while (*c != '\0')
135     {
136         if (*c == '0')
137             n = n->lchild;
138         else
139             n = n->rchild;
140         c++;
141     }
142     return n->character;
143 }
 
 

见证奇迹的时刻到啦!

如此,便实现了哈夫曼编码与解码啦~~

 
 

 

转载于:https://www.cnblogs.com/to-sunshine/p/5986055.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值