• HuffmanTree


    huffmanTree.h

      1 #include <STDIO.H>
      2 #include <STDLIB.H>
      3 #include <MALLOC.H>
      4 #include <STRING.H>
      5 
      6 #define MAXSIZE 10
      7 
      8 typedef struct
      9 {
     10     unsigned int weight;
     11     unsigned int left,right,parent;
     12 }HTNode,* HuffmanTree;
     13 
     14 typedef char * * HuffmanCode;
     15 
     16 void Select(HuffmanTree HT,int end,int &s1,int &s2);
     17 
     18 void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int w[],int n)
     19 {
     20     if(n <= 1)
     21     {
     22         return;
     23     }
     24 
     25     int m = 2*n-1,i,s1 = 1,s2 = 2;
     26     char *col;
     27     HT = (HuffmanTree)malloc(sizeof(HTNode)*(m+1));//这里0号单元没有使用
     28     HuffmanTree pt = HT;
     29     pt++;
     30 
     31     for(i = 1;i <= n;i++,w++,pt++)
     32     {
     33         pt->weight = *w;
     34         pt->left = 0;
     35         pt->right = 0;
     36         pt->parent = 0;
     37     }
     38     for(;i <= m;i++,pt++)
     39     {
     40         pt->weight = 0;
     41         pt->left = 0;
     42         pt->right = 0;
     43         pt->parent = 0;
     44     }
     45 
     46     for(i = n+1;i <= m;i++)//构造哈夫曼树
     47     {
     48         Select(HT,i-1,s1,s2);
     49         HT[i].left = s1;
     50         HT[i].right = s2;
     51         HT[i].weight = HT[s1].weight + HT[s2].weight;
     52         HT[s1].parent = i;
     53         HT[s2].parent = i;
     54     }
     55 
     56     //---第一种方法求哈夫曼编码,逆序
     57     /*
     58     HC = (HuffmanCode)malloc(sizeof(char *)*(n+1));
     59     col = (char *)malloc(sizeof(char)*n);
     60     col[n-1] = '\0';
     61 
     62     for(i = 1;i <= n;i++)
     63     {
     64         unsigned int start = n-1,p,f;
     65         p = f = i;
     66         while(HT[f].parent != 0)
     67         {
     68             f = HT[f].parent;
     69             if(HT[f].left == p)
     70             {
     71                 col[--start] = '0';
     72             }
     73             else if(HT[f].right == p)
     74             {
     75                 col[--start] = '1';
     76             }
     77             p = f;
     78         }
     79         HC[i] = (char *)malloc(sizeof(char)*(n-start));
     80         strcpy(HC[i],&col[start]);
     81         printf("%s\n",HC[i]);
     82     }
     83 
     84     free(col);
     85     */
     86 
     87     //---第二种方法求哈夫曼编码,正序
     88     for(i = 1;i <= m;i++)
     89     {
     90         HT[i].weight = 0;
     91     }
     92 
     93     col = (char *)malloc(sizeof(char)*n);
     94     HC = (HuffmanCode)malloc(sizeof(char *)*(n+1));
     95     //p作为循环终止条件,当遍历完成后p会退回到树根的parent即0,此时应该终止循环,而往下倒叶子节点时是不会为0的,因此可以作为循环条件
     96     int p = m,colen = 0;
     97 
     98     while(p)
     99     {
    100         if(HT[p].weight == 0)
    101         {
    102             HT[p].weight = 1;
    103             if(HT[p].left != 0)
    104             {
    105                 p = HT[p].left;
    106                 col[colen++] = '0';
    107             }
    108             else if(HT[p].right == 0)
    109             {
    110                 HC[p] = (char *)malloc(sizeof(char)*(colen+1));
    111                 strncpy(HC[p],col,colen);
    112                 HC[p][colen] = '\0';
    113             }
    114         }
    115         else if(HT[p].weight == 1)
    116         {
    117             HT[p].weight = 2;
    118             if(HT[p].right != 0)
    119             {
    120                 p = HT[p].right;
    121                 col[colen++] = '1';
    122             }
    123         }
    124         else
    125         {
    126             HT[p].weight = 0;
    127             p = HT[p].parent;
    128             colen--;//变量名写准了,不能写错
    129         }
    130     }
    131 
    132 }
    133 
    134 void Select(HuffmanTree HT,int end,int &s1,int &s2)//从1到end之间选择最小的2个元素的下标
    135 {
    136     int i = 1;
    137     unsigned int min1,min2;//min1和min2存放parent为0的最小的2个元素
    138 
    139     while(HT[i].parent != 0 && i <= end)//寻找第一个未访问的元素下标,if还是while一定要判断准确了,脑子清楚,不要犯低级错误
    140     {
    141         i++;
    142     }
    143     if(i == end+1)
    144     {
    145         return;
    146     }
    147     s1 = i;
    148     min1 = HT[i].weight;
    149     i++;
    150     while(HT[i].parent != 0 && i <= end)//寻找第二个未访问的元素下标,!还是不!一定要判断准确了才行,逻辑要理清楚
    151     {
    152         i++;
    153     }
    154     if(i == end+1)
    155     {
    156         return;
    157     }
    158     s2 = i;
    159     min2 = HT[i].weight;
    160     i++;
    161     if(min1 > min2)
    162     {
    163         unsigned int temp = min1;
    164         min1 = min2;
    165         min2 = temp;
    166         temp = s1;
    167         s1 = s2;
    168         s2 = temp;
    169     }
    170     for(;i <= end;i++)
    171     {
    172         if(HT[i].parent == 0)
    173         {
    174             if(HT[i].weight < min1)
    175             {
    176                 s2 = s1;
    177                 s1 = i;
    178                 min2 = min1;
    179                 min1 = HT[i].weight;
    180             }
    181             else if(HT[i].weight < min2)
    182             {
    183                 s2 = i;
    184                 min2 = HT[i].weight;
    185             }
    186         }
    187     }
    188 }

    main.cpp

     1 #include "huffmanTree.h"
     2 
     3 int main()
     4 {
     5     int a[4] = {4,2,1,5};
     6     HuffmanTree ht;
     7     HuffmanCode hc;
     8     HuffmanCoding(ht,hc,a,4);
     9     for(int i = 1;i <= 4;i++)
    10     {
    11         //printf("%d  %s \n",ht[i].weight,hc[i]);
    12         printf("%s\n",hc[i]);
    13     }
    14 
    15     system("pause");
    16     return 0;
    17 }
  • 相关阅读:
    设计模式总结——程序猿武功秘籍(下一个)
    easyui datagrid显示进度条控制操作
    使用CountDownLatch和CyclicBarrier处理并发线程
    人类探索地外文明显著取得的进展
    Linux 启动过程的详细解释
    不会跳回到微博认定申请书
    unix域套接字UDP网络编程
    VS SQL 出现%CommonDir%dte80a.olb 该解决方案
    数据仓库与数据挖掘的一些基本概念
    CheckBoxPreference组件
  • 原文地址:https://www.cnblogs.com/maowang1991/p/2806288.html
Copyright © 2020-2023  润新知