最优编码不一定通过Huffman算法得到,
比如交换该题等长编码元素的位置
#include <iostream>
#include <string>
#define MAXN 64
#define MINDATA -1
using namespace std;
struct node
{
int weight;
char cha;
node* left;
node* right;
};
char c[MAXN],f[MAXN];
node** H;int H_size,H_capacity;
int N;
int sum;
void BulidH(){
H_size=0;
H_capacity=N;
H=new node*[H_capacity+1];
H[0]=new node;
H[0]->weight=MINDATA;
}
void InsertH(node* x){
H_size++;
int i;
for(i=H_size;H[i/2]->weight>x->weight;i=i/2){
H[i]=H[i/2];
}
H[i]=x;
}
node* DeleteH(){
node* min=H[1];
H[1]=H[H_size];H_size--;
node* x=H[1];
int parent,child;
for(parent=1;parent*2<=H_size;parent=child){
child=parent*2;
if(child!=H_size && H[child+1]->weight<H[child]->weight){
child++;
}
if(H[child]->weight>x->weight) break;
else H[parent]=H[child];
}
H[parent]=x;
return min;
}
node* BuildHuffmanTree(){
node* HT;
//注意DeleteH会影响size从而影响i取值
for(int i=1;i<H_capacity;i++){
HT=new node;
HT->left=DeleteH();
HT->right=DeleteH();
HT->weight=HT->left->weight+HT->right->weight;
InsertH(HT);
}
HT=DeleteH();
return HT;
}
int VisitLeaves(node* HT,int depth){
//HT没有度为一的结点,因此不用考虑只有一个孩子的情况
if(!HT->left && !HT->right) return HT->weight*depth;
return VisitLeaves(HT->left,depth+1)+VisitLeaves(HT->right,depth+1);
}
void BulidTree(){
node* T;
T=new node;T->weight=-1;T->left=NULL;T->right=NULL;
string code[N];
int flag=1;
int sum1=0;
for(int i=0;i<N;i++){
getline(cin,code[i]);
//1:输入长度判定
if(code[i].length()>N+1) flag=0;
//2:WSL判定
sum1=sum1+(code[i].length()-2)*f[i];
//3:前缀码判定
node* tmp=T;
for(int j=2;j<code[i].length();j++){
if(code[i][j]=='0'){
if(!tmp->left){
tmp->left=new node;
tmp=tmp->left;tmp->left=NULL;tmp->right=NULL;
tmp->weight=-1;
}else{
if(tmp->weight==-1) tmp=tmp->left;
else{
flag=0;break;
}
}
}else{
if(!tmp->right){
tmp->right=new node;
tmp=tmp->right;tmp->left=NULL;tmp->right=NULL;
tmp->weight=-1;
}else{
if(tmp->weight==-1) tmp=tmp->right;
else{
flag=0;break;
}
}
}
}
if(!tmp->left && !tmp->right && tmp->weight==-1){
tmp->weight=(code[i].length()-2)*f[i];
}else{
flag=0;
}
}
if(flag && (sum1==sum)) cout<<"Yes";
else cout<<"No";
}
int main(){
scanf("%d",&N);
BulidH();
node* tmp;
for(int i=0;i<N;i++){
//为了建Huffman树读入的时候就要新建结点
getchar();
tmp=new node;
scanf("%c %d",&tmp->cha,&tmp->weight);
tmp->left=NULL;tmp->right=NULL;
InsertH(tmp);
//保存一下每个结点的权,因为测试数据是按顺序的,因此不存字母其实也行
c[i]=tmp->cha;f[i]=tmp->weight;
}
node* HT=BuildHuffmanTree();
sum=VisitLeaves(HT,0);
int times;
scanf("%d\n",×);
//解决末尾回车问题
int k=0;
for(int i=0;i<times;i++){
if(k){
cout<<endl;
BulidTree();
}else{
BulidTree();
k=1;
}
}
system("pause");
return 0;
}