huffman.c
上传用户:xs588588
上传日期:2021-03-30
资源大小:242k
文件大小:3k
源码类别:

DSP编程

开发平台:

C/C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define TRUE 1
  4. #define FALSE 0
  5. // 编码的最大位数
  6. #define MAXBITS 50
  7. // 最大的字符数
  8. #define MAXSYMBS MAXBITS
  9. // 树中的最大节点
  10. #define MAXNODES 2 * MAXSYMBS-1
  11. struct CodeType {
  12. int nBits[MAXBITS];
  13. int nStartPos;
  14. };
  15. struct NodeType {
  16. int nFrequency;
  17. int nParent;
  18. int iSLeft;
  19. };
  20. // 队列的插入删除处理
  21. void QueueInsert(int nWhich);
  22. int QueueDelete(void);
  23. // 定义全局变量
  24. struct NodeType node[MAXNODES];
  25. // 队列最初位空
  26. int rootnodes = -1;
  27. void main(void)
  28. {
  29. struct CodeType cd, code[MAXSYMBS];
  30. int i;
  31. int nSymbolsNum;
  32. int nBitCount;
  33. int nNextNode;
  34. int nLeftNode, nRightNode;
  35. int root;
  36. int thisnode;
  37. char symbol, alphabet[MAXSYMBS];
  38. // 清空字符数组
  39. for(i = 0; i < MAXSYMBS; i++)
  40. {
  41. alphabet[i] = ' ';
  42. }
  43. /*// 有多少个字符
  44. printf("Please input char's countn");
  45. scanf("%d", &nSymbolsNum);
  46. printf("Please input char and frequenciesn");
  47. // 得到数据和每个字符的频率
  48. for(i = 0; i < nSymbolsNum; i++)
  49. {
  50. scanf("%s%d", &symbol, &node[i].nFrequency);
  51. QueueInsert(i);
  52. alphabet[i] = symbol;
  53. }*/
  54. //构造信源数据
  55. nSymbolsNum = 3;
  56. alphabet[0] = 'a';
  57. node[0].nFrequency = 8;
  58. QueueInsert(0);
  59. alphabet[1] = 'b';
  60. node[1].nFrequency = 2;
  61. QueueInsert(1);
  62. alphabet[2] = 'c';
  63. node[2].nFrequency = 5;
  64. QueueInsert(2);
  65. // 形成Huffman树
  66. for(nNextNode =  nSymbolsNum;
  67. nNextNode < 2 * nSymbolsNum - 1;
  68. nNextNode ++)
  69. {
  70. nLeftNode = QueueDelete();
  71. nRightNode = QueueDelete();
  72. // 形成新的树,作为子节点
  73. node[nLeftNode].nParent = nNextNode;
  74. node[nRightNode].nParent = nNextNode;
  75. node[nLeftNode].iSLeft = TRUE;
  76. node[nRightNode].iSLeft = FALSE;
  77. // 父节点的频率是两个子节点频率之和
  78. node[nNextNode].nFrequency = 
  79. node[nLeftNode].nFrequency + node[nRightNode].nFrequency;
  80. //插入节点
  81. QueueInsert( nNextNode);
  82. }
  83.     // 根节点
  84. root = QueueDelete();
  85. // 根据树进行编码
  86. for(i = 0; i < nSymbolsNum; i++)
  87. {
  88. // 搜索的初始点
  89. cd.nStartPos = MAXBITS;
  90. // 对树进行遍历,对内容进行编码
  91. thisnode = i;
  92. while(thisnode != root)
  93. {
  94. --cd.nStartPos;
  95. cd.nBits[cd.nStartPos] = node[thisnode].iSLeft ? 0 : 1;
  96. thisnode = node[thisnode].nParent;
  97. }
  98. // 内容拷贝
  99. for(nBitCount = cd.nStartPos; nBitCount < MAXBITS; nBitCount++)
  100. {
  101. code[i].nBits[nBitCount] = cd.nBits[nBitCount];
  102. }
  103. code[i].nStartPos = cd.nStartPos;
  104. }
  105. for(i = 0; i < nSymbolsNum; i++)
  106. {
  107. printf("n%c %d ", alphabet[i], node[i].nFrequency);
  108. for(nBitCount = code[i].nStartPos; nBitCount < MAXBITS; nBitCount++)
  109. {
  110. printf("%d", code[i].nBits[nBitCount]);
  111. }
  112. printf("n");
  113. }
  114. }
  115. // 将节点插入到队列里
  116. void QueueInsert(int nWhich)
  117. {
  118. int thisnode, previous;
  119. // 队列是否为空
  120. if(rootnodes == -1)
  121. {
  122. // 空队列
  123. node[nWhich].nParent = -1;
  124. rootnodes = nWhich;
  125. }
  126. else
  127. {
  128. thisnode = rootnodes; 
  129. previous = -1;
  130. //搜索大的节点
  131. while((thisnode != -1) && 
  132. (node[thisnode].nFrequency < node[nWhich].nFrequency))
  133. {
  134. previous = thisnode;
  135. thisnode = node[thisnode].nParent;
  136.   }
  137. // 连接到第一个大的节点
  138. node[nWhich].nParent = thisnode;
  139. if(previous != -1)
  140. {
  141. // 拷贝
  142. node[previous].nParent = nWhich;
  143. }
  144. else
  145. {
  146. // 插入到开始位置
  147. rootnodes = nWhich;
  148. }
  149. }
  150. }
  151. //从优先队列里去掉第一个结点
  152. int QueueDelete(void)
  153. {
  154. int thisnode = rootnodes;
  155. rootnodes = node[thisnode].nParent;
  156. return thisnode;
  157. }