题158.pta数据结构题集-05-树9 Huffman Codes (30 分)
一、题目
二、题解
本题要你判断所给的编码是否正确。依据题意,编码正确需要满足两个条件:第一是编码长度和哈夫曼编码长度相等,第二是编码不会出现前缀问题。代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef struct Tnode *HFM;
struct Tnode
{
char data;
int weight;
int len;//用于记录路径长度
HFM left,right;
};
struct TnodeCmp//构造Tnode比较器,用于建立优先队列的小顶堆
{
bool operator() (Tnode *t1,Tnode *t2)
{
return t1->weight>t2->weight;//从堆的底部到顶部降序
}
};
int N;
char data0[100];
int weight[100];
priority_queue<Tnode*,vector<Tnode*>,TnodeCmp> pq;
void init()//输入构建哈夫曼树的数据
{
cin>>N;
for(int i=0;i<N;i++)
{
HFM T=new Tnode;
cin>>data0[i]>>weight[i];
T->data=data0[i];
T->weight=weight[i];
T->left=NULL;
T->right=NULL;
pq.push(T);
}
}
HFM buildTree()//建立哈夫曼树
{
init();
while(pq.size()>1)
{
HFM T1=pq.top();
pq.pop();
HFM T2=pq.top();
pq.pop();
HFM T=new Tnode;
T->weight=T1->weight+T2->weight;
T->left=T1;
T->right=T2;
pq.push(T);
}
return pq.top();
}
int getWplOfHFM(HFM BT)//bfs得到哈夫曼树的WPL值,即所谓的哈夫曼编码长度
{
int res=0;
HFM T=BT;
queue<HFM> q;
q.push(T);
T->len=0;
while(!q.empty())
{
HFM TempT=q.front();
q.pop();
if(TempT->left==NULL&&TempT->right==NULL)
{
res+=TempT->len*TempT->weight;//求权*路径长的和
}
if(TempT->left!=NULL)
{
q.push(TempT->left);
TempT->left->len=TempT->len+1;//下一个节点的路径长为当前节点路径长+1
}
if(TempT->right!=NULL)
{
q.push(TempT->right);
TempT->right->len=TempT->len+1;
}
}
return res;
}
int main()
{
HFM T=buildTree();
int WPL0=getWplOfHFM(T);
int M;
cin>>M;
for(int i=0;i<M;i++)
{
int WPL=0;
string codes[N];
int flag=1;
for(int j=0;j<N;j++)
{
char data;
cin>>data>>codes[j];
WPL+=codes[j].length()*weight[j];//计算该编码的WPL值,即所谓的编码长度
}
if(WPL==WPL0)//比较编码长度和哈夫曼编码长度
{
for(int j=0;j<N;j++)
{
for(int k=0;k<N;k++)
{
if(j!=k&&codes[j].find(codes[k])==0)//判断编码是否出现前缀问题
{
flag=0;
break;
}
}
}
}
else
{
flag=0;
}
if(flag)
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
}
}