一、 实验目的
熟练掌握哈夫曼树的建立和哈夫曼编码的算法实现。
二、 实验内容
根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求赫夫曼编码,并能把给定的编码进行译码。
三、 实验要求
(1)初始化:从键盘输入一字符串(或读入一文件),统计出现的字符和每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树。对各个字符进行哈夫曼编码,最后打印输出字符及每个字符对应的哈夫曼编码。
(2)编码:利用已建好的哈夫曼树对“输入串”进行哈夫曼编码,最后打印输入串对应的哈夫曼编码(写入文件)。
(3)计算压缩比(选作)
(4)译码:利用已建好的哈夫曼树对给定的一串代码进行译码,并打印输出得到的字符串。(选作)
测试数据:对字符串{casbcatbsatbat}进行编码;对电文“1101000”译码。字符集D={ ?},出现频率为w={?}
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <sstream> 13 const int INF=0x3f3f3f3f; 14 typedef long long LL; 15 const int mod=1e9+7; 16 const int maxn=1e4+10; 17 using namespace std; 18 19 struct node 20 { 21 int val;//权值 22 int lc;//左孩子 23 int rc;//右孩子 24 int parent;//双亲 25 char c;//节点字符 26 int flag;//标志 27 }Huffman_Tree[26*2]; 28 29 int num[26]={0};//每种字符的个数 30 char Huffman_code[26][100];//每种字符对应的编码 31 char str[maxn];//原字符串 32 int cnt;//Huffman树节点个数计数器 33 34 void Init()//初始化 35 { 36 printf("请输入一串字符串(该字符串只能为小写字母): "); 37 gets(str); 38 for(int i=0;str[i];i++) 39 { 40 num[str[i]-'a']++; 41 } 42 int sum=0; 43 for(int i=0;i<26;i++) 44 { 45 if(num[i])//初始化 46 { 47 sum++; 48 Huffman_Tree[++cnt].c=i+'a'; 49 Huffman_Tree[cnt].val=num[i]; 50 Huffman_Tree[cnt].lc=0; 51 Huffman_Tree[cnt].rc=0; 52 Huffman_Tree[cnt].parent=0; 53 Huffman_Tree[cnt].flag=0; 54 } 55 } 56 for(int k=0;k<sum-1;k++)//建树 57 { 58 int MIN1=INF; 59 int MIN2=INF; 60 int Index1,Index2; 61 for(int i=1;i<=cnt;i++) 62 { 63 if(Huffman_Tree[i].flag==0) 64 { 65 if(Huffman_Tree[i].val<MIN1) 66 { 67 MIN2=MIN1; 68 Index2=Index1; 69 MIN1=Huffman_Tree[i].val; 70 Index1=i; 71 } 72 else if(Huffman_Tree[i].val<MIN2) 73 { 74 MIN2=Huffman_Tree[i].val; 75 Index2=i; 76 } 77 } 78 } 79 Huffman_Tree[Index1].flag=1; 80 Huffman_Tree[Index2].flag=1; 81 int t=MIN1+MIN2; 82 Huffman_Tree[++cnt].val=t; 83 Huffman_Tree[cnt].c='*'; 84 Huffman_Tree[cnt].lc=Index1; 85 Huffman_Tree[cnt].rc=Index2; 86 Huffman_Tree[cnt].parent=0; 87 Huffman_Tree[cnt].flag=0; 88 Huffman_Tree[Index1].parent=cnt; 89 Huffman_Tree[Index2].parent=cnt; 90 } 91 for(int i=0;i<26;i++)//求Huffman编码 92 { 93 if(num[i]) 94 { 95 char tem[100]; 96 int len=0; 97 int p; 98 for(int j=1;j<=cnt;j++) 99 { 100 if(Huffman_Tree[j].c==i+'a') 101 { 102 p=j; 103 break; 104 } 105 } 106 while(Huffman_Tree[p].parent) 107 { 108 if(Huffman_Tree[Huffman_Tree[p].parent].lc==p) 109 tem[len++]='0'; 110 else 111 tem[len++]='1'; 112 p=Huffman_Tree[p].parent; 113 } 114 tem[len]='