哈夫曼编码_哈夫曼树_详细注释版本

课堂上丧心病狂要默写哈夫曼编码。。。表示已跪ORZ。

下来重新看了下,表示网上的版本有点难懂,自己搞了个简单易读版本,附带详细注释

  1 #include <iostream>
  2 #include <Windows.h>
  3 #define INFINITY 65535
  4 using namespace std;
  5 typedef struct
  6 {
  7     int weight;                    //权值
  8     int parent, Left, Right;    //左右孩子的节点值
  9 }TREE, *PTREE;
 10 typedef char **TheCode;//指向TheCode(逆转编码值)的一个指针
 11 void HuffmanCoding(PTREE &HuffmanTree, int *w, int n);    
 12 void Find_Min_(PTREE HuffmanTree,int n, int &The_Min_Numb_NO_1, int &The_Min_Numb_NO_2);//选择书中节点值较小的两个节点
 13 int w[] = {8, 9,4, 12,33,56,32,45};    //各节点权值
 14 void HuffmanCoding(PTREE &HuffmanTree, int *w, int n)
 15 {
 16     
 17     int m = 2 * n - 1; //哈夫曼树一共有m个节点
 18     HuffmanTree = (TREE*)malloc((m + 1) * sizeof(TREE));//Huffman tree的所有节点
 19 
 20     int The_Min_Numb_NO_1, The_Min_Numb_NO_2; //声明两个节点,其权重为最小的两个
 21 
 22     memset(HuffmanTree, 0, (m + 1)* sizeof(TREE));    //对所有节点初始化为-0
 23     for (int i = 1; i <= n; i++)
 24     {
 25         HuffmanTree[i].weight = *w++;    //可改变为人为输入————把自动提供的数字输入到哈夫曼节点当中
 26     }
 27 
 28     //创建Huffman tree
 29     for(int i = n + 1; i <= m; ++i)
 30     {
 31         //选择剩余节点中权值较小的The_Min_Numb_NO_1和The_Min_Numb_NO_2
 32         Find_Min_(HuffmanTree, i - 1, The_Min_Numb_NO_1, The_Min_Numb_NO_2);
 33         HuffmanTree[The_Min_Numb_NO_1].parent = i;
 34         HuffmanTree[The_Min_Numb_NO_2].parent = i;
 35         HuffmanTree[i].Left = The_Min_Numb_NO_1;
 36         HuffmanTree[i].Right = The_Min_Numb_NO_2;
 37         HuffmanTree[i].weight = HuffmanTree[The_Min_Numb_NO_1].weight + HuffmanTree[The_Min_Numb_NO_2].weight;
 38     }
 39 
 40     TheCode The_Inverse_Arry_;
 41     int start, c, f;
 42     The_Inverse_Arry_ = (TheCode)malloc((n + 1) * sizeof(char*));  
 43     char* cd = (char*)malloc(n * sizeof(char));
 44     cd[n - 1] = '\0';
 45     for(int i = 1; i <= n; i++)
 46     {
 47         start = n - 1;
 48         for(c = i, f = HuffmanTree[i].parent; f != 0; c = f, f = HuffmanTree[f].parent)
 49             if (HuffmanTree[f].Left == c) //对于所有点,如果找到了他的左儿子节点
 50                 cd[--start] = '0';        //对于所有左节点而言,他的code值为0
 51             else
 52                 cd[--start] = '1';       //同上,对于右边而言,code值为1
 53         The_Inverse_Arry_[i] = (char*)malloc((n - start) * sizeof(char));//申明逆转数组
 54         strcpy(The_Inverse_Arry_[i], &cd[start]);       //逆转code数组(因为是从叶子节点往上的)
 55     }
 56 
 57     for (int i = 1; i <= n; i++)
 58     {
 59         cout<< HuffmanTree[i].weight<<" 的哈夫曼代码是 ";
 60         cout<<The_Inverse_Arry_[i]<<endl;
 61     }
 62 }
 63 
 64 void Find_Min_(PTREE HuffmanTree, int n, int &The_Min_Numb_NO_1, int &The_Min_Numb_NO_2)
 65 {
 66     The_Min_Numb_NO_1 = 1;
 67     The_Min_Numb_NO_2 = 1;
 68     int min  = INFINITY;
 69     int i;
 70     //选择未被使用的第一个节点,
 71     for (i = 1; i <= n; ++i)
 72     {
 73         if (HuffmanTree[i].parent == 0)
 74         {
 75             min = HuffmanTree[i].weight;
 76             break;
 77         }
 78     }
 79 
 80     //找到权值最小点The_Min_Numb_NO_1
 81     for (int p =  1; p <= n; ++p)
 82     {
 83         if(0 == HuffmanTree[p].parent && min >= HuffmanTree[p].weight)
 84         {
 85             The_Min_Numb_NO_1 = p;
 86             min = HuffmanTree[p].weight;
 87         }
 88     }
 89     //找到The_Min_Numb_NO_2
 90     min = INFINITY;
 91     for (int q =  1; q <= n; ++q)
 92     {
 93         if(0 == HuffmanTree[q].parent && min >= HuffmanTree[q].weight )
 94         {
 95             if( q == The_Min_Numb_NO_1)
 96                 continue;
 97             The_Min_Numb_NO_2 = q;
 98             min = HuffmanTree[q].weight;
 99         }
100     }
101 }
102 int main()
103 {
104     PTREE HuffmanTree;
105     HuffmanCoding(HuffmanTree, w, 8);
106     return 0;
107 }

 

posted @ 2016-11-02 16:18  Madao东治  阅读(410)  评论(0编辑  收藏  举报