哈夫曼编码

哈夫曼编码的抽象数据结构

1 typedef struct
2 {
3     int weigth;
4     int parent;
5     int lchild;
6     int rchild;
7 }HTNode, * HuffmanTree;/*动态分配数组存储哈夫曼树*/

求哈夫曼编码的算法

 1 void HuffmanCoding(HuffmanTree* HT, char*** HC, int* W, int n)
 2 {/* 指针W指向的数组中存放 n 个字符的权值(均>0),构造哈夫曼树HT ,并求出 n 个字符的哈夫曼编码HC*/
 3     int i = 0;
 4     int s1 = 0;
 5     int s2 = 0;
 6     int start = 0;
 7     int child = 0;
 8     int parent = 0;
 9     int m = 2 * n - 1;
10     char* str = NULL;
11     HuffmanTree P = NULL;
12 
13     if (n <= 1)
14     {
15         return;
16     }
17 
18     (*HT) = (HuffmanTree)calloc(m + 1, sizeof(HTNode));/*0号单元未使用*/
19     for (P = (*HT) + 1, i = 1; i <= n; ++i, ++P, ++W)
20     {
21         P->weigth = *W;
22     }
23     for (i = n + 1; i <= m; ++i)/*建哈夫曼树*/
24     {
25         Select((*HT), i - 1, &s1, &s2);/*在 HT[1... i - 1]选择 parent 为 0 且 weigth 值最小的两个结点,其序号分别为 s1 和 s2*/
26         (*HT)[s1].parent = i;
27         (*HT)[s2].parent = i;
28         (*HT)[i].lchild = s1;
29         (*HT)[i].rchild = s2;
30         (*HT)[i].weigth = (*HT)[s1].weigth + (*HT)[s2].weigth;
31     }
32 
33     /*下面从叶子到根逆向求每个字符的哈夫曼编码*/
34     (*HC) = (char**)calloc(n + 1, sizeof(char*));
35     str = (char*)calloc(n, sizeof(char));/*临时编码数组*/
36     str[n - 1] = '\0';/*从后向前逐位求编码,首先放编码结束符*/
37     for (i = 1; i <= n; ++i)
38     {
39         start = n - 1;
40         for (child = i, parent = (*HT)[i].parent; parent != 0; child = parent, parent = (*HT)[parent].parent)
41         {
42             if ((*HT)[parent].lchild == child)
43             {
44                 str[--start] = '0';
45             }
46             else
47             {
48                 str[--start] = '1';
49             }
50             (*HC)[i] = (char*)calloc(n - start, sizeof(char));
51             strcpy((*HC)[i], &str[start]);
52         }
53     }
54     free(str);
55 }

在权值数组中寻找权值最小的两个结点

 1 void Select(HuffmanTree HT, int N, int* s1, int* s2)
 2 {/*在 HT[1... N]选择 parent 为 0 且 weigth 值最小的两个结点,其序号分别为 s1 和 s2*/
 3     int i = 1;
 4     for (i = 1; i <= N; ++i)
 5     {/*设s1初值*/
 6         if (HT[i].parent == 0)
 7         {
 8             (*s1) = i;
 9             break;
10         }
11     }
12     for (i = 1; i <= N; ++i)
13     {/*找s1*/
14         if (HT[i].parent == 0 && HT[i].weigth < HT[(*s1)].weigth)
15         {
16             (*s1) = i;
17         }
18     }
19 
20     for (i = 1; i <= N; ++i)
21     {/*设s2初值*/
22         if (HT[i].parent == 0 && i != (*s1))
23         {
24             (*s2) = i;
25             break;
26         }
27     }
28     for (i = 1; i <= N; ++i)
29     {/*找s2*/
30         if (HT[i].parent == 0 && HT[i].weigth < HT[(*s2)].weigth && i != (*s1))
31         {
32             (*s2) = i;
33         }
34     }
35 }
View Code

源代码

  1 /*-------------------------------------------------------------------------
  2  * Name:   哈夫曼编码源代码
  3  * Date:   2022.01.15
  4  * Author: 吕辉
  5  * 在 Visual Studio Community 2022 下测试通过
  6  *------------------------------------------------------------------------*/
  7 #define _CRT_SECURE_NO_WARNINGS
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #include <string.h>
 11 
 12 typedef struct
 13 {
 14     int weigth;
 15     int parent;
 16     int lchild;
 17     int rchild;
 18 }HTNode, * HuffmanTree;/*动态分配数组存储哈夫曼树*/
 19 
 20 void HuffmanCoding(HuffmanTree* HT, char*** HC, int* W, int n);
 21 void Select(HuffmanTree HT, int N, int* s1, int* s2);
 22 
 23 int main(void)
 24 {
 25     HuffmanTree HT = NULL;
 26     char** HC = NULL;
 27     int weight[8] = { 5, 29, 7, 8, 14, 23, 3, 11 };
 28     int* W = weight;
 29     int n = 8;
 30     int i = 0;
 31 
 32     HuffmanCoding(&HT, &HC, W, n);
 33 
 34     for (i = 1; i <= n; i++)
 35     {
 36         printf("权值为%2d的哈夫曼码为:%s\n", HT[i].weigth, HC[i]);
 37     }
 38 
 39     system("pause");
 40     return 0;
 41 }
 42 void HuffmanCoding(HuffmanTree* HT, char*** HC, int* W, int n)
 43 {/* 指针W指向的数组中存放 n 个字符的权值(均>0),构造哈夫曼树HT ,并求出 n 个字符的哈夫曼编码HC*/
 44     int i = 0;
 45     int s1 = 0;
 46     int s2 = 0;
 47     int start = 0;
 48     int child = 0;
 49     int parent = 0;
 50     int m = 2 * n - 1;
 51     char* str = NULL;
 52     HuffmanTree P = NULL;
 53 
 54     if (n <= 1)
 55     {
 56         return;
 57     }
 58 
 59     (*HT) = (HuffmanTree)calloc(m + 1, sizeof(HTNode));/*0号单元未使用*/
 60     for (P = (*HT) + 1, i = 1; i <= n; ++i, ++P, ++W)
 61     {
 62         P->weigth = *W;
 63     }
 64     for (i = n + 1; i <= m; ++i)/*建哈夫曼树*/
 65     {
 66         Select((*HT), i - 1, &s1, &s2);/*在 HT[1... i - 1]选择 parent 为 0 且 weigth 值最小的两个结点,其序号分别为 s1 和 s2*/
 67         (*HT)[s1].parent = i;
 68         (*HT)[s2].parent = i;
 69         (*HT)[i].lchild = s1;
 70         (*HT)[i].rchild = s2;
 71         (*HT)[i].weigth = (*HT)[s1].weigth + (*HT)[s2].weigth;
 72     }
 73 
 74     /*下面从叶子到根逆向求每个字符的哈夫曼编码*/
 75     (*HC) = (char**)calloc(n + 1, sizeof(char*));
 76     str = (char*)calloc(n, sizeof(char));/*临时编码数组*/
 77     str[n - 1] = '\0';/*从后向前逐位求编码,首先放编码结束符*/
 78     for (i = 1; i <= n; ++i)
 79     {
 80         start = n - 1;
 81         for (child = i, parent = (*HT)[i].parent; parent != 0; child = parent, parent = (*HT)[parent].parent)
 82         {
 83             if ((*HT)[parent].lchild == child)
 84             {
 85                 str[--start] = '0';
 86             }
 87             else
 88             {
 89                 str[--start] = '1';
 90             }
 91             (*HC)[i] = (char*)calloc(n - start, sizeof(char));
 92             strcpy((*HC)[i], &str[start]);
 93         }
 94     }
 95     free(str);
 96 }
 97 
 98 void Select(HuffmanTree HT, int N, int* s1, int* s2)
 99 {/*在 HT[1... N]选择 parent 为 0 且 weigth 值最小的两个结点,其序号分别为 s1 和 s2*/
100     int i = 1;
101     for (i = 1; i <= N; ++i)
102     {/*设s1初值*/
103         if (HT[i].parent == 0)
104         {
105             (*s1) = i;
106             break;
107         }
108     }
109     for (i = 1; i <= N; ++i)
110     {/*找s1*/
111         if (HT[i].parent == 0 && HT[i].weigth < HT[(*s1)].weigth)
112         {
113             (*s1) = i;
114         }
115     }
116 
117     for (i = 1; i <= N; ++i)
118     {/*设s2初值*/
119         if (HT[i].parent == 0 && i != (*s1))
120         {
121             (*s2) = i;
122             break;
123         }
124     }
125     for (i = 1; i <= N; ++i)
126     {/*找s2*/
127         if (HT[i].parent == 0 && HT[i].weigth < HT[(*s2)].weigth && i != (*s1))
128         {
129             (*s2) = i;
130         }
131     }
132 }
View Code

 

posted @ 2022-01-15 05:19  吕辉  阅读(120)  评论(0)    收藏  举报