编程练习——huffman编码

这个类的名字叫huffman Tree,但是不仅仅是生成huffman Tree,因为Huffman树的生成要使用优先队列,也就是堆。stl中其实有这个的实现。但是我机器里的vs2005这个堆的使用有点小bug(估计是stl中使用的就是数组存储,而且数组一旦固定大小,就再也无法改变,其实这样实现失去了堆的某些特性。所以我还是自己实现了一下。顺便练习下。)。刚开始的时候就采用int作为编码的存储单元。后来发现huffman是可变长编码。所以使用int作为编码单元就失去了huffman的特性。于是寻找bit数组。找到了bitset这个stl类,却发现这个是不可变的。无语。只得自己实现一个可变大小的bit vector。然后近乎重写了这个Huffman的编码和解码。不过也不是很难。在这之间又陆陆续续的发现了一系列的bug和编译错误。对以后的编程大有启发。

  1. /*createdbychicochen
  2. *date2008/10/25
  3. */
  4. #ifndef_HUFFMAN_TREE_
  5. #define_HUFFMAN_TREE_
  6. #include"Heap.h"
  7. #include"TreeNode.h"
  8. #include"BinaryTree.h"
  9. #include<map>
  10. #include"../../ArithmeticTest/ArithmeticTest/BITVector.h"
  11. usingnamespacestd;
  12. //thisclassisusedforthecombinfunctioninhuffmanTreeclass.
  13. classIntCombin
  14. {
  15. public:
  16. staticintAdd(inti,intj)
  17. {
  18. returni+j;
  19. }
  20. };
  21. //thisclassforcomparetreenode
  22. template<classT>
  23. classTreeNodeCompare
  24. {
  25. public:
  26. staticboolUp(TreeNode<T>*d1,TreeNode<T>*d2)
  27. {
  28. returnLt(d1->getData(),d2->getData());
  29. }
  30. staticboolEq(T&d1,T&d2)
  31. {
  32. if(d1==d2)
  33. returntrue;
  34. returnfalse;
  35. }
  36. staticboolGt(T&d1,T&d2)
  37. {
  38. if(d1>d2)
  39. returntrue;
  40. returnfalse;
  41. }
  42. staticboolLt(T&d1,T&d2)
  43. {
  44. if(d1<d2)
  45. returntrue;
  46. returnfalse;
  47. }
  48. };
  49. //thisclassisforstoringhuffmancode.
  50. //bitsandthelengthofbits
  51. classHuffmanCode
  52. {
  53. public:
  54. BITVectorbits;
  55. intlen;
  56. HuffmanCode()
  57. {
  58. len=0;
  59. }
  60. HuffmanCode(constHuffmanCode&codes):bits(codes.bits)
  61. {
  62. len=codes.len;
  63. }
  64. constHuffmanCode&operator=(constHuffmanCode&codes)
  65. {
  66. if(this!=&codes)
  67. {
  68. this->len=codes.len;
  69. this->bits=codes.bits;
  70. }
  71. return*this;
  72. }
  73. ~HuffmanCode()
  74. {
  75. }
  76. };
  77. template<classT,classCmp,classCombin>
  78. classHuffmanTree:publicBinaryTree<T>
  79. {
  80. private:
  81. //storethedata,andsortit,thenforbuildingahuffmantree
  82. Heap<TreeNode<T>*,Cmp>huffmanQueue;
  83. constunsignedintmask;
  84. //themaxnumbercanbeshifted,ifitisunsignedintthenitwillbe32.
  85. constintmaxShiftNum;
  86. TreeNode<T>*initTree()
  87. //initthehuffmantree
  88. {
  89. TreeNode<T>*combinNode=NULL;
  90. TtempData;
  91. while(!this->huffmanQueue.IsEmpty())
  92. {
  93. //fetchtwosmalldataandgeneratealargedata
  94. TreeNode<T>*node1=this->huffmanQueue.Top();
  95. combinNode=node1;
  96. this->huffmanQueue.RemoveTop();
  97. if(!this->huffmanQueue.IsEmpty())
  98. {
  99. TreeNode<T>*node2=this->huffmanQueue.Top();
  100. this->huffmanQueue.RemoveTop();
  101. tempData=Combin::Add(node1->getData(),node2->getData());
  102. if(Cmp::Lt(node1->getData(),node2->getData()))
  103. {
  104. //hereiscomparingthedata1ofnode1andthedata2ofnode2
  105. //Cmp:Ltmeans'<'andCmp:Gtmeans'>'
  106. combinNode=newTreeNode<T>(tempData,node1,node2);
  107. }
  108. else
  109. {
  110. combinNode=newTreeNode<T>(tempData,node2,node1);
  111. }
  112. this->huffmanQueue.Insert(combinNode);
  113. }
  114. else
  115. {
  116. break;
  117. }
  118. }
  119. returncombinNode;
  120. }
  121. //thefinalhuffmancode
  122. map<T,HuffmanCode>huffmanTable;
  123. voidSelfEncode(TreeNode<T>*subRoot,unsignedintbitcode,intnum,map<T,HuffmanCode>&ht)
  124. //encodingthedatafromahuffmantree.
  125. //Theleftbranchis0,andtherightbranchis1
  126. {
  127. if(subRoot!=NULL)
  128. {
  129. if(subRoot->left==NULL&&subRoot->right==NULL)
  130. {
  131. HuffmanCodehc;
  132. hc.bits.SetInt(bitcode,0,maxShiftNum-num);
  133. hc.len=maxShiftNum-num;
  134. ht[subRoot->getData()]=hc;
  135. return;
  136. }
  137. else
  138. {
  139. if(num<=0)
  140. {
  141. throw"thehuffmanistoodeep!";
  142. }
  143. SelfEncode(subRoot->left,bitcode,num-1,ht);
  144. bitcode=bitcode|(0x80000000>>(maxShiftNum-num));
  145. SelfEncode(subRoot->right,bitcode,num-1,ht);
  146. }
  147. }
  148. }
  149. voidDecodeFromTree(TreeNode<T>*subRoot,BITVector&bits,intindex,constint&len,vector<T>&decode)
  150. //decodingthecode.usethecodetosearchthedatafromthehuffmanTree.
  151. //hereyoucancreateyouownmap<code,data>deHuffmanTable.
  152. //butIcannotanalyzethespacethetablewilluse,
  153. //soIfindthedatabysearchinghuffmantree
  154. {
  155. if(index==len)
  156. {
  157. if(subRoot->getLeft()==NULL&&subRoot->getRight()==NULL)
  158. {
  159. decode.push_back(subRoot->getData());
  160. return;
  161. }
  162. throw"codelengthisnotmatchthebitslength.HuffmanTreeconstructerror.";
  163. }
  164. if(subRoot==NULL)
  165. {
  166. throw"decodeerror!";
  167. }
  168. elseif(subRoot->getLeft()==NULL&&subRoot->getRight()==NULL)
  169. {
  170. decode.push_back(subRoot->getData());
  171. returnDecodeFromTree(this->root,bits,index,len,decode);
  172. }
  173. if(bits.Get(index)==0)
  174. {
  175. returnDecodeFromTree(subRoot->getLeft(),bits,index+1,len,decode);
  176. }
  177. elseif(bits.Get(index)==1)
  178. {
  179. returnDecodeFromTree(subRoot->getRight(),bits,index+1,len,decode);
  180. }
  181. else
  182. {
  183. throw"codeerror!";
  184. }
  185. }
  186. unsignedintFindCodeFromTable(T&data)
  187. //findthedatacodefromhuffmantable
  188. //maybenotefficient.
  189. {
  190. returnthis->huffmanTable[data];
  191. }
  192. public:
  193. HuffmanTree(Tt[],intn):
  194. BinaryTree<T>(),mask(0x80000000),maxShiftNum(sizeof(unsignedint)*8)
  195. //thearrayttypeisT,andthenumberisn
  196. {
  197. if(n==0)
  198. return;
  199. TreeNode<T>*node;
  200. for(inti=0;i<n;i++)
  201. {
  202. node=newTreeNode<T>(t[i]);
  203. this->huffmanQueue.Insert(node);
  204. }
  205. this->root=initTree();
  206. }
  207. ~HuffmanTree()
  208. {
  209. //destroy
  210. }
  211. voidSelfEncode()
  212. //convertthehuffmanTreeintohuffmanTable
  213. //unsignedintcodeis32bits,sothehuffmantreehasonlylessthan33layer.
  214. {
  215. strings="";
  216. SelfEncode(this->root,0,maxShiftNum,this->huffmanTable);
  217. }
  218. voidDecode(HuffmanCode&huffmanCode,vector<T>&decode)
  219. //usebittofindthedatanode.
  220. {
  221. returnDecodeFromTree(this->root,huffmanCode.bits,0,huffmanCode.len,decode);
  222. }
  223. HuffmanCodeEncode(Tinfo[],intn)
  224. //nissize
  225. {
  226. HuffmanCodehc;
  227. for(inti=0;i<n;i++)
  228. {
  229. hc.bits.SetBitVector(((HuffmanCode)this->huffmanTable[info[i]]).bits,hc.len,((HuffmanCode)this->huffmanTable[info[i]]).len);
  230. hc.len+=((HuffmanCode)this->huffmanTable[info[i]]).len;
  231. }
  232. returnhc;
  233. }
  234. voidPrintHuffmanTable()
  235. //printthehuffmantable
  236. //printthepairdata<->code
  237. {
  238. intlen=this->huffmanTable.size();
  239. cout<<"i/tdata/tcode/n";
  240. intcount=0;
  241. map<T,HuffmanCode>::iteratori=this->huffmanTable.begin();
  242. for(;i!=this->huffmanTable.end();i++)
  243. {
  244. cout<<count++<<"/t"<<(*i).first<<"/t";
  245. (*i).second.bits.PrintfZeroOne(0,(*i).second.len);
  246. cout<<endl;
  247. }
  248. }
  249. };
  250. #endif

这个类设计方面还有些不足之处。比如encode方法

测试一下:

  1. inta[10]={12,224,33,32,1,91,35,34,36,291};
  2. HuffmanTree<int,TreeNodeCompare<int>,IntCombin>ht(a,10);
  3. ht.SelfEncode();
  4. ht.PrintHuffmanTable();
  5. ht.printTree();
  6. cout<<endl;
  7. intinfo[]={33,34,33};
  8. HuffmanCodehc=ht.Encode(info,3);
  9. hc.bits.PrintfZeroOne(0,hc.len);
  10. vector<int>code;
  11. ht.Decode(hc,code);
  12. for(inti=0;i!=code.size();i++)
  13. {
  14. cout<<code[i]<<endl;
  15. }
  16. return0;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值