按词频从小到大的顺序给出各个字符(不超过30个)的词频,根据词频构造哈夫曼树,给出每个字符的哈夫曼编码,并对给出的语句进行译码。为确保构建的哈夫曼树唯一,本题做如下限定:
(1)选择根结点权值最小的两棵二叉树时,选取权值较小者作为左子树。
(2)若多棵二叉树根结点权值相等,按先后次序分左右,先出现的作为左子树,后出现的作为右子树。
生成哈夫曼编码时,哈夫曼树左分支标记为0,右分支标记为1。
类型定义以及函数接口定义:
typedef struct hnode
{
char ch;
int weight;
int lchild,rchild;
int parent;
} huffNode,*huffmanTree;
typedef char **HuffmanCode; //动态二维数组,用于存储每个字符的编码
void Select(huffmanTree &HT, int k, int &s1, int &s2);
//从HT数组的0到up-1中找出father为-1的且权重最小的结点赋给s1,s2,(为了保证答案唯一,请让s1的结点编号小于s2)
void CreateHuffTree(huffmanTree &HT, char str[],int W[ ], int N );
//创建哈夫曼树,W为权重数组,N为叶子结点个数
void HuffmanEnCode(huffmanTree HT,HuffmanCode &HC,int N);
//从叶子到根逆向求每个字符的哈夫曼编码,并存储在编码表HC中,N是字符个数
void show(huffmanTree HT,HuffmanCode HC,int N);
void HuffmanDeCode(huffmanTree HT,int N,char str[]);
//根据哈夫曼树HT,对字符串str的进行译码,N是字符个数
样例代码程序:
#include
#include <string.h>
using namespace std;
typedef struct hnode
{
char ch;
int weight;
int lchild,rchild;
int parent;
} huffNode,*huffmanTree;
typedef char **HuffmanCode; //动态二维数组,用于存储每个字符的编码
void Select(huffmanTree &HT, int k, int &s1, int &s2);
//从HT数组的0到up-1中找出father为-1的且权重最小的结点赋给s1,s2,(为了保证答案唯一,请让s1的结点编号小于s2)
void CreateHuffTree(huffmanTree &HT, char str[],int W[ ], int N );
//创建哈夫曼树,W为权重数组,N为叶子结点个数
void HuffmanEnCode(huffmanTree HT,HuffmanCode &HC,int N);
void show(huffmanTree HT,HuffmanCode HC,int N);
void HuffmanDeCode(huffmanTree HT,int N,char str[]);
int main()
{
huffmanTree HT;
HuffmanCode HC;
char *str;
int i,N,*W;
cin>>N; //输入节点个数
W = new int[N]; //申请动态数组,存储N个节点的权值
str=new char[N];
HT=new huffNode[2*N-1]; //申请动态数组,存储2*N-1个节点
for(i = 0; i < N; i++)
{
cin>>str[i]>>W[i]; //读入N个节点的权值
}
CreateHuffTree(HT,str,W,N);
HuffmanEnCode(HT,HC,N);
show(HT,HC,N);
delete str;
str=new char[100];
cin>>str;
// cout<<str;
cout<<"\noriginal:";
HuffmanDeCode(HT,N,str);
delete W;
delete HC;
delete HT;
return 0;
}
void CreateHuffTree(huffmanTree &HT, char str[],int W[ ], int N )
{
int i,i1,i2,k;
for (i = 0; i < N; i++) //叶子结点初始化
{
HT[i].parent = -1;
HT[i].lchild = -1;
HT[i].rchild = -1;
HT[i].weight = W[i];
HT[i].ch=str[i];
}
for (k = N; k < 2*N-1; k++)
{
Select(HT,k, i1, i2);
HT[k].weight = HT[i1].weight+HT[i2].weight;
HT[k].lchild = i1;
HT[k].rchild = i2;
HT[k].parent=-1;
HT[i1].parent = k;
HT[i2].parent = k;
}
}
void show(huffmanTree HT,HuffmanCode HC,int N)
{
for(int i=0; i<N; i++)
cout<<HT[i].ch<<":"<<HC[i]<<endl;
}
//你的代码写在这里 ,注意提交完整程序进行测试
输入格式:
第一行输入字符个数n;
第二行到第n行输入相应的字符及其词频(可以是整数,与可以是小数);
最后一行输入需进行译码的串。
输出格式
首先按树的先序顺序输出所有字符的编码,每个编码占一行;
最后一行输出需译码的原文,加上original:字样。
输出中均无空格
输入样例
3
m1
n1
c2
10110
输出样例
m:10
n:11
c:0
original:mnc
有点长 不过你可以去网上看看