哈夫曼编码

哈夫曼编码的抽象数据结构
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 }
源代码
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 }

浙公网安备 33010602011771号