数据结构——哈夫曼树及哈夫曼编码代码实现

Dear 丶 2024-04-18 16:49 204阅读 0赞
  1. #define MAXLEAFNUM 50 //最优二叉树中的最多叶子数目
  2. typedef struct node{
  3. char ch;//结点表示的字符
  4. int weight;//权值
  5. int parent;//结点的父结点的下标,为0表示无父结点
  6. int lChild,rChild;//结点的左右孩子结点的下标,为0表示无孩子结点
  7. }HuffmanTree[2*MAXLEAFNUM];
  8. typedef char* HuffmanCode[MAXLEAFNUM + 1];
  9. void select(HuffmanTree HT,int n,int &s1,int &s2)
  10. {
  11. s1 = 1;
  12. s2 = 2;
  13. int nMinW = HT[1].weight;
  14. for(int i = 1; i <= n;i++){
  15. if(HT[i].parent != 0){
  16. continue;
  17. }
  18. if(nMinW > HT[i].weight){
  19. nMinW = HT[i].weight;
  20. s1 = i;
  21. }
  22. }
  23. if(s1 != 1){
  24. nMinW = HT[1].weight;
  25. }else{
  26. nMinW = HT[2].weight;
  27. }
  28. for(int i = 1; i <= n -1;i++){
  29. if(HT[i].parent != 0 || i == s1){
  30. continue;
  31. }
  32. if(nMinW > HT[i].weight){
  33. nMinW = HT[i].weight;
  34. s2 = i;
  35. }
  36. }
  37. }
  38. //创建哈夫曼树
  39. void createHTree(HuffmanTree HT,char *c,int *w,int n)
  40. {
  41. int i,s1,s2;
  42. if(n <= 1){
  43. return;
  44. }
  45. for(i = 1; i <= n;i++){//构造n棵只有根结点的树
  46. HT[i].ch = c[i - 1];
  47. HT[i].weight = w[i - 1];
  48. HT[i].parent = HT[i].lChild = HT[i].rChild = 0;
  49. }
  50. for(;i < 2 * n;i++){
  51. HT[i].parent = HT[i].lChild = HT[i].rChild = 0;
  52. }
  53. for(i = n + 1; i < 2 *n; i++){
  54. select(HT,i - 1,s1,s2);
  55. HT[s1].parent = i;
  56. HT[s2].parent = i;
  57. HT[i].lChild = s1;
  58. HT[i].rChild = s2;
  59. HT[i].weight = HT[s1].weight + HT[s2].weight;
  60. }
  61. }
  62. //根据给定的哈夫曼树,从每个叶子结点出发追溯到根,逆向找出最优二叉树中叶子结点的编码
  63. //n个叶子结点在哈夫曼HT中的下标为1~n,第i(1<= i <= n)个叶子的编码存放在HC[i]中
  64. void HuffmanCoding(HuffmanTree HT,HuffmanCode HC,int n)
  65. {
  66. char *cd;
  67. int i,start,c,f;
  68. if(n <= 1){
  69. return;
  70. }
  71. cd = (char*)malloc( n * sizeof(char));//申请足够的空间存储编码
  72. cd[n -1] = '\0';//结尾符
  73. for(i = 1; i <= n;i++){
  74. start = n - 1;
  75. for(c = i,f = HT[i].parent;f != 0;c = f,f = HT[f].parent){//执行完一次后继续向上回溯结点
  76. if(HT[f].lChild == c){//如果当前结点与父结点的左节点相等,则对应字符编码为0,否则为1
  77. cd[start] = '0';
  78. }else{
  79. cd[start] = '1';
  80. }
  81. start--;
  82. }
  83. HC[i] = (char*)malloc((n - start) * sizeof(char));
  84. strcpy(HC[i],&cd[start]);
  85. free(cd);
  86. }
  87. }
  88. //利用最优二叉树译码
  89. void Decoding(HuffmanTree HT,int n,char *buff)
  90. {
  91. int p = 2 * n - 1;
  92. while (*buff) {
  93. if((*buff) == '0'){
  94. p = HT[p].lChild;
  95. }else{
  96. p = HT[p].rChild;
  97. }
  98. if(HT[p].lChild == 0 && HT[p].rChild == 0){
  99. cout << HT[p].ch << endl;
  100. p = 2 * n - 1;
  101. }
  102. buff++;
  103. }
  104. }

发表评论

表情:
评论列表 (有 0 条评论,204人围观)

还没有评论,来说两句吧...

相关阅读

    相关 编码

    哈夫曼树 给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径