哈夫曼编解码(C语言)

x33g5p2x  于2021-11-12 转载在 其他  
字(3.5k)|赞(0)|评价(0)|浏览(423)

哈夫曼编解码(C语言)

示例

输入:
helllllllo

生成码表:
a:00010010
b:00010011
c:00010100
d:00010101
e:001
f:00010110
g:00010111
h:010
i:00011000
j:00011001
k:00011010
l:1
m:00011011
n:00011100
o:011
p:00011101
q:00011110
r:00011111
s:0000000
t:0000001
u:0000010
v:0000011
w:0000100
x:0000101
y:0000110
z:0000111

编码结果:
0100011111111011

解码结果:
helllllllo

代码实现

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #define maxsize 1000 /* 编码函数中,被编译的字符串的最大长度 */
  5. #define max 1000 /* 最大字符的个数 */
  6. typedef struct {
  7. char data; /* 数据域 */
  8. int weight; /* 权值域 */
  9. int parent;
  10. int left;
  11. int right;
  12. } huffNode;
  13. typedef struct {
  14. char code[max]; // 存放哈夫曼编码
  15. int start;
  16. } huffCode;
  17. huffNode *initFrequency(int count[]) // 初始化带权结点
  18. {
  19. static huffNode ht[2 * max];
  20. ht[0].weight = 27; /* 字符个数 */
  21. ht[1].data = ' ';
  22. ht[1].weight = count[26]; // space
  23. for (int i = 1; i <= 27; i++) {
  24. ht[i].data = (char) ('a' + i - 1);
  25. ht[i].weight = count[i - 1];
  26. }
  27. return ht;
  28. }
  29. void buildTree(huffNode *ht) {
  30. /* m1为最小权值,x1为其在ht中的下标;m2为第二小权值,x2为其下标 */
  31. int i, k, x1, x2, n, m1, m2;
  32. n = ht[0].weight;
  33. for (i = 1; i <= 2 * n - 1; i++)
  34. ht[i].parent = ht[i].left = ht[i].right = 0; /* 对ht的parent,left,right域进行初始化 */
  35. for (i = n + 1; i <= 2 * n - 1; i++) {
  36. m1 = m2 = 10000; /* m1,m2初值无限大 */
  37. x1 = x2 = 0; /* x1, x2初值为0 */
  38. for (k = 1; k <= i - 1; k++) {/* k为可以进行比较的结点的下标 */
  39. if (ht[k].parent == 0) { /* 当前结点的父结点不存在时 */
  40. if (ht[k].weight < m1) /* 当前结点的权值比最小权值还小时 */
  41. {
  42. m2 = m1;
  43. x2 = x1;
  44. m1 = ht[k].weight;
  45. x1 = k;
  46. } else if (ht[k].weight < m2) { /* 当前结点的权值比最小权值大但比第二最小权值小时 */
  47. m2 = ht[k].weight;
  48. x2 = k;
  49. }
  50. }
  51. }
  52. ht[x1].parent = i;
  53. ht[x2].parent = i;
  54. ht[i].weight = ht[x1].weight + ht[x2].weight;
  55. ht[i].left = x1;
  56. ht[i].right = x2;
  57. }
  58. }
  59. huffCode *printHuffmanCode(huffNode *hNode) {
  60. static huffCode hCode[max];
  61. huffCode d;
  62. int i, n, c, f, k, x;
  63. n = hNode[0].weight;
  64. for (i = 1; i <= n; i++) {
  65. d.start = n + 1;
  66. c = i;
  67. f = hNode[i].parent;
  68. while (f != 0) {
  69. if (hNode[f].left == c) d.code[--d.start] = '0';
  70. else d.code[--d.start] = '1';
  71. c = f;
  72. f = hNode[f].parent;
  73. }
  74. hCode[i] = d;
  75. }
  76. printf("huffman code table:\n");
  77. for (i = 1; i <= n; i++) {
  78. printf("%c:", hNode[i].data);
  79. x = hCode[i].start;
  80. for (k = x; k <= n; k++) {
  81. printf("%c", hCode[i].code[k]);
  82. }
  83. printf("\n");
  84. }
  85. return hCode;
  86. }
  87. huffCode *encoding(huffCode *hCode, huffNode *hNode) {
  88. int i, j, n, m, k, x;
  89. char in[maxsize], out[2 * maxsize];
  90. int count[27] = {0};
  91. m = 0;
  92. printf("input a string:");
  93. getchar();
  94. gets(in);
  95. n = strlen(in);
  96. for (i = 0; i < n; i++) {
  97. if (in[i] >= 'a' && in[i] < 'z') {
  98. count[in[i] - 'a']++;
  99. }
  100. if (in[i] == ' ')count[26]++;
  101. if (in[i] == '0') break;
  102. }
  103. hNode = initFrequency(count);
  104. buildTree(hNode);
  105. hCode = printHuffmanCode(hNode);
  106. for (i = 0; i < n; i++) {
  107. for (j = 1; j <= hNode[0].weight; j++) {
  108. if (in[i] == hNode[j].data) {
  109. x = hCode[j].start;
  110. for (k = x; k <= hNode[0].weight; k++) {
  111. out[m++] = hCode[j].code[k];
  112. }
  113. }
  114. }
  115. }
  116. printf("\nThe encoding result is:\n");
  117. for (i = 0; i < m; i++) {
  118. printf("%c", out[i]);
  119. }
  120. return hNode;
  121. }
  122. void decoding(huffCode hcd[], huffNode ht[]) {
  123. int i, j, n, k, x, m, w;
  124. char in[maxsize * 2], out[maxsize];
  125. printf("\nenter huffman code:\n");
  126. scanf("%s", in);
  127. n = strlen(in);
  128. i = 0;
  129. m = 0;
  130. while (i < n) {
  131. for (j = 1; j <= ht[0].weight; j++) {
  132. x = hcd[j].start;
  133. for (k = x, w = i; k <= ht[0].weight; k++, w++) {
  134. if (in[w] != hcd[j].code[k]) {
  135. break;
  136. }
  137. }
  138. if (k > ht[0].weight) {
  139. out[m++] = ht[j].data;
  140. break;
  141. }
  142. }
  143. i = w;
  144. }
  145. for (i = 0; i < m; i++) {
  146. printf("%c", out[i]);
  147. }
  148. }
  149. int main() {
  150. int select;
  151. huffNode *hNode;
  152. huffCode *hCode;
  153. do {
  154. printf("\n\n");
  155. printf("--------------------------Menu-----------------------------\n");
  156. printf("1. input string\n");
  157. printf("2. input code\n");
  158. printf("-----------------------------------------------------------\n\n");
  159. printf("choose 1 or 2: ");
  160. scanf("%d", &select);
  161. if (select == 1) {
  162. hNode = encoding(hCode, hNode);
  163. } else if (select == 2) {
  164. hCode = printHuffmanCode(hNode);
  165. decoding(hCode, hNode);
  166. } else {
  167. printf("No such option. Exit.\n");
  168. exit(1);
  169. }
  170. } while (1);
  171. }

相关文章