关于哈夫曼编码
这只是一个最最最简单的代码!!!
本代码功能:输入字符串中字符种类数以及每个字符出现的频数,可以得到每个字符对应的哈夫曼编码并输出
日常练习得到,如果有改良版,比如直接输入字符串便可输出每个字符对应的哈夫曼编码并且可以解码,这样会在后续发布(如果成功的话。。。)
现在是代码
主函数:
1 #include <iostream> 2 #include "哈夫曼树.h" 3 using namespace std; 4 int main() { 5 HuffmanTree HT; 6 HuffmanCode HC; 7 int *wei, n; 8 char *ch; 9 char string[100]; 10 cout << "请输入元素种类数:"; 11 cin >> n; 12 cout << "请依次输入各元素及出现出现的次数" << endl; 13 int i; 14 wei = (int *)malloc((n + 1) * sizeof(int)); 15 ch = (char*)malloc((n + 1) * sizeof(char)); 16 for (i = 1; i <= n; i++) { 17 cout << "第" << i <<"个元素:" << endl; 18 cout << "元素名:"; 19 cin >> ch[i]; 20 cout << "元素出现次数:"; 21 cin >> wei[i]; 22 } 23 cout << "输入完成,感谢配合!" << endl; 24 //这里是函数执行操作,待会再来 25 createHuffmanTree(&HT, n, wei, ch); 26 createHuffmanCode(&HT, &HC, n); 27 return 0; 28 }
哈夫曼树.cpp
1 include <iostream> 2 #include "哈夫曼树.h" 3 using namespace std; 4 //找权值最小的结点 5 void select(HuffmanTree *huffmantree,int n,int *s1,int *s2) { 6 int i;//作为计数器 7 int min1, min2, m1=0, m2;//权值最小和权值次小,权值最小和次小所在位置 8 min1 = 999; 9 min2 = 999; 10 for (i = 1; i <= n; i++) { 11 if ((*huffmantree)[i].parent == 0) {//保证父节点不为0 12 if (min1 > (*huffmantree)[i].weight) { 13 min2 = min1; 14 m2 = m1; 15 min1 = (*huffmantree)[i].weight; 16 m1 = i; 17 } 18 else if (min2 > (*huffmantree)[i].weight) { 19 min2 = (*huffmantree)[i].weight; 20 m2 = i; 21 } 22 } 23 } 24 *s1 = m1; 25 *s2 = m2; 26 } 27 //初始化节点,构造哈夫曼树 28 void createHuffmanTree(HuffmanTree *huffmantree,int n,int w[],char cha[]) { 29 int i; 30 int m = 2 * n - 1; 31 *huffmantree = (HuffmanTree)malloc((m + 1) * sizeof(Node)); 32 //叶子节点的初始化 33 for (i = 1; i <= n; i++) { 34 (*huffmantree)[i].parent = 0; 35 (*huffmantree)[i].lchild = 0; 36 (*huffmantree)[i].rchild = 0; 37 (*huffmantree)[i].c = cha[i]; 38 (*huffmantree)[i].weight = w[i]; 39 } 40 //非叶子节点的初始化 41 for (i = n + 1; i <= m; i++) { 42 (*huffmantree)[i].parent = 0; 43 (*huffmantree)[i].lchild = 0; 44 (*huffmantree)[i].rchild = 0; 45 (*huffmantree)[i].weight = 0; 46 } 47 //开始构建哈夫曼树 48 cout << "哈夫曼树:" << endl; 49 cout << "父节点权值 (左孩子权值 右孩子权值)" << endl; 50 int s1, s2;//这是两个权值最小的结点所在位置 51 for (i = n + 1; i <= m; i++) { 52 //寻找parent为0,且权值最小的两个结点 53 select(huffmantree, i-1, &s1, &s2); 54 (*huffmantree)[s1].parent = i; 55 (*huffmantree)[s2].parent = i; 56 (*huffmantree)[i].lchild = s1; 57 (*huffmantree)[i].rchild = s2; 58 (*huffmantree)[i].weight = (*huffmantree)[s1].weight + (*huffmantree)[s2].weight; 59 cout << " " << (*huffmantree)[i].weight << " " << (*huffmantree)[s1].weight << " " << (*huffmantree)[s2].weight << endl; 60 } 61 } 62 //初始化哈夫曼编码?!生成哈夫曼编码 63 void createHuffmanCode(HuffmanTree *huffmantree,HuffmanCode *huffmancode,int n) { 64 int i, start, f; 65 char *cd; 66 int c; 67 huffmancode = (HuffmanCode*)malloc((n + 1) * sizeof(char*));//n个头指针向量 68 cd = (char*)malloc(n * sizeof(char)); 69 cd[n - 1] = '\0';//编码结束符 70 for (i = 1; i <= n; ++i) { 71 start = n - 1; 72 for (c = i, f = (*huffmantree)[i].parent; f != 0; c = f, f = (*huffmantree)[f].parent) { 73 if ((*huffmantree)[f].lchild == c) cd[--start] = '0'; 74 else cd[--start] = '1'; 75 } 76 //为第i个字符编码分配空间 77 huffmancode[i] = (char*)malloc((n - start) * sizeof(char)); 78 strcpy(huffmancode[i], &cd[start]); 79 } 80 free(cd); 81 //开始打印编码 82 cout << "哈夫曼字符 权值 对应编码" << endl; 83 for (i = 1; i <= n; i++) { 84 cout << " " << (*huffmantree)[i].c << " " << (*huffmantree)[i].weight << " " << huffmancode[i] << endl; 85 } 86 }
哈夫曼.h
1 #include <iostream> 2 using namespace std; 3 typedef struct { 4 int weight; 5 int lchild, rchild, parent; 6 char c; 7 }Node, *HuffmanTree; 8 typedef char *HuffmanCode; 9 void select(HuffmanTree *huffmantree, int n, int *s1, int *s2); 10 void createHuffmanTree(HuffmanTree *huffmantree, int n, int w[], char cha[]); 11 void createHuffmanCode(HuffmanTree *huffmantree, HuffmanCode *huffmancode, int n);
大概就是这样