虽然东西简单了点,可能还有错,读者们别介意它太啰嗦,有更好的建议欢迎交流的。放出来希望对像我一样学习编程的人有帮助(虽然看别人的代码貌似是件很痛苦的事啊)。
这里没有用模板函数(人比较懒),,节点的权值都是int,,类函数定义都在类的内部
//哈夫曼树类
class Node
{
public:
Node *rchild;
Node *lchild;
Node *parent;
int weight; //权值
char ch; //叶子字符
char node_code; //每个字符对应的路径(左0右1)
Node(){};
};
class HuffmanTree
{
protected:
Node *root; //根节点
vector<char> leaf_char; //从叶节点得到字符
vector<string> leaf_code ; //保存每个字符的编码
public:
HuffmanTree(int p ,char c){root=new Node();root->weight=p;root->ch=c;}
HuffmanTree(){root=new Node();}
void build_tree(int pro[],char cha[],int count)
{
HuffmanTree *r[26];
for(int j=0;j<count;j++) //初始化每个字符形成的树
{
r[j]=new HuffmanTree() ;
r[j]->root->ch=cha[j];
r[j]->root->weight=pro[j];
}
for(int j=0;j<count-1;j++) //找出数组中根节点权值最小的两个 合并
{
for(int i=j+1;i<count;i++) //找出最小权值的树放入r[j]
{
if(r[j]->root->weight>r[i]->root->weight)
{
HuffmanTree *temp;
temp=r[i];
r[i]=r[j];
r[j]=temp;
}
}
for(int i=j+2;i<count;i++) //找出最小权值的树放入r[j+1]
{
if(r[j+1]->root->weight>r[i]->root->weight)
{
HuffmanTree *temp;
temp=r[i];
r[i]=r[j+1];
r[j+1]=temp;
}
}
HuffmanTree *t_r=new HuffmanTree(); //过渡用的t_r 生成新的树赋给r[j+1]
t_r->root->lchild=r[j]->root;
r[j]->root->parent=t_r->root;
r[j]->root->node_code='0'; //是parent的左孩子,赋予路径0
t_r->root->rchild=r[j+1]->root;
r[j+1]->root->parent=t_r->root;
r[j+1]->root->node_code='1'; //是parent的左孩子,赋予路径1
t_r->root->weight = r[j]->root->weight+r[j+1]->root->weight; //左右孩子的权值和
r[j+1]=t_r;
if(j+1==count-1)
root=r[j+1]->root;
}
}
void turn_char_code(Node *h) //输出每个字符的编码
{
string s;
Node *temp=h;
if(temp->lchild==NULL && temp->rchild==NULL) //测到根节点
{
char c=temp->ch;
leaf_char.push_back(temp->ch);
while (temp->parent!=NULL) //有父节点则推测哈夫曼编码
{
s=temp->node_code+s;
temp=temp->parent;
}
leaf_code.push_back(s);
cout<<c<<"的哈夫曼编码:"<<s<<endl;
}
if(h->lchild!=NULL)
{
turn_char_code(h->lchild);
}
if(h->rchild!=NULL)
{
turn_char_code(h->rchild);
}
}
string turn_string_code(string src) //返回字符串的哈夫曼编码
{
string h_string;
turn_char_code(root);
for(int j=0;j<src.length();j++)
{
for(int k=0;k<leaf_char.size();k++)
{
if(src[j]==leaf_char[k])
h_string=h_string+leaf_code[k];
}
}
return h_string;
}
string deCode(string src)
{
string s;
for(int j=0;j<src.length();)
{
for(int k=0;k<leaf_char.size();k++)
{
int code_length=leaf_code[k].length();
if(src.substr(j,code_length)==leaf_code[k]) //以j开头的code_length个字符为字串与leaf_code对比
{
s=s+leaf_char[k];
j=j+code_length;
}
}
}
return s;
}
};
string huffmancoding(const string &src)
{
cout << "=========== Huffman coding ===========" << endl;
cout << "Input string : " << src << endl;
string destCode;
/// 在此处添加编码代码,输入为src,输出为destCode
int p[26];
char c[26];
c[0]=src[0];
//字符串的各字符不重复地放入c[]
int c_count=1; //数组c[]的数量
for(int j=0;j<src.length();j++)
{
int k=0;
for(k=0;k<c_count;k++) //寻找当前的字符在c[]中是否有记录
{
if(c[k]==src[j]) //有记录则跳出循环 且k=0
{
k=0;
break;
}
}
if(k>0) //在c[]中未找到当前字符
{
c_count++;
c[c_count-1]=src[j];
}
}
//计算src中各字符的出现次数 相对应记录于p[]
for(int j=0;j<=c_count;j++)
{
p[j]=0;
for(int h=0;h<src.length();h++)
{
if(src[h]==c[j])
p[j]++;
}
}
HuffmanTree h_tree;
h_tree.build_tree(p,c,c_count);
cout << "===== Code for each char :" << endl;
destCode=h_tree.turn_string_code(src);
cout << "Coded string : " << destCode << endl;
/// 此处输出每个字符的编码
//哈夫曼树类
class Node
{
public:
<span > </span>Node *rchild;
<span > </span>Node *lchild;
<span > </span>Node *parent;
<span > </span>int weight; //权值
<span > </span>char ch; //叶子字符
<span > </span>char node_code; //每个字符对应的路径(左0右1)
<span > </span>Node(){};
};
class HuffmanTree
{
protected:
<span > </span>Node *root; //根节点
<span > </span>vector<char> leaf_char; //从叶节点得到字符
<span > </span>vector<string> leaf_code ; //保存每个字符的编码
public:
<span > </span>HuffmanTree(int p ,char c){root=new Node();root->weight=p;root->ch=c;}
<span > </span>HuffmanTree(){root=new Node();}
<span > </span>void build_tree(int pro[],char cha[],int count)
<span > </span>{
<span > </span>HuffmanTree *r[26];
<span > </span>for(int j=0;j<count;j++) //初始化每个字符形成的树
<span > </span>{
<span > </span>r[j]=new HuffmanTree() ;
<span > </span>r[j]->root->ch=cha[j];
<span > </span>r[j]->root->weight=pro[j];
<span > </span>
<span > </span>}
<span > </span>for(int j=0;j<count-1;j++) //找出数组中根节点权值最小的两个 合并
<span > </span>{
<span > </span>for(int i=j+1;i<count;i++) //找出最小权值的树放入r[j]
<span > </span>{
<span > </span>if(r[j]->root->weight>r[i]->root->weight)
<span > </span>{
<span > </span>HuffmanTree *temp;
<span > </span>temp=r[i];
<span > </span>r[i]=r[j];
<span > </span>r[j]=temp;
<span > </span>}
<span > </span>}
<span > </span>for(int i=j+2;i<count;i++) //找出最小权值的树放入r[j+1]
<span > </span>{
<span > </span>if(r[j+1]->root->weight>r[i]->root->weight)
<span > </span>{
<span > </span>HuffmanTree *temp;
<span > </span>temp=r[i];
<span > </span>r[i]=r[j+1];
<span > </span>r[j+1]=temp;
<span > </span>}
<span > </span>}
<span > </span>HuffmanTree *t_r=new HuffmanTree(); //过渡用的t_r 生成新的树赋给r[j+1]
<span > </span>t_r->root->lchild=r[j]->root;
<span > </span>r[j]->root->parent=t_r->root;
<span > </span>r[j]->root->node_code='0'; //是parent的左孩子,赋予路径0
<span > </span>t_r->root->rchild=r[j+1]->root;
<span > </span>r[j+1]->root->parent=t_r->root;
<span > </span>r[j+1]->root->node_code='1'; //是parent的左孩子,赋予路径1
<span > </span>t_r->root->weight = r[j]->root->weight+r[j+1]->root->weight; //左右孩子的权值和
<span > </span>r[j+1]=t_r;
<span > </span>if(j+1==count-1)
<span > </span>root=r[j+1]->root;
<span > </span>}
<span > </span>}
<span > </span>void turn_char_code(Node *h) //输出每个字符的编码
<span > </span>{
<span > </span>string s;
<span > </span>Node *temp=h;
<span > </span>if(temp->lchild==NULL && temp->rchild==NULL) //测到根节点
<span > </span>{
<span > </span>char c=temp->ch;
<span > </span>leaf_char.push_back(temp->ch);
<span > </span>while (temp->parent!=NULL) //有父节点则推测哈夫曼编码
<span > </span>{
<span > </span>s=temp->node_code+s;
<span > </span>temp=temp->parent;
<span > </span>}
<span > </span>leaf_code.push_back(s);
<span > </span>cout<<c<<"的哈夫曼编码:"<<s<<endl;
<span > </span>}
<span > </span>if(h->lchild!=NULL)
<span > </span>{
<span > </span>turn_char_code(h->lchild);
<span > </span>}
<span > </span>if(h->rchild!=NULL)
<span > </span>{
<span > </span>turn_char_code(h->rchild);
<span > </span>}
<span > </span>}
<span > </span>string turn_string_code(string src) //返回字符串的哈夫曼编码
<span > </span>{
<span > </span>string h_string;
<span > </span>turn_char_code(root);
<span > </span>for(int j=0;j<src.length();j++)
<span > </span>{
<span > </span>for(int k=0;k<leaf_char.size();k++)
<span > </span>{
<span > </span>if(src[j]==leaf_char[k])
<span > </span>h_string=h_string+leaf_code[k];
<span > </span>}
<span > </span>}
<span > </span>return h_string;
<span > </span>}
<span > </span>string deCode(string src)
<span > </span>{
<span > </span>string s;
<span > </span>for(int j=0;j<src.length();)
<span > </span>{
<span > </span>for(int k=0;k<leaf_char.size();k++)
<span > </span>{
<span > </span>int code_length=leaf_code[k].length();
<span > </span>if(src.substr(j,code_length)==leaf_code[k]) //以j开头的code_length个字符为字串与leaf_code对比
<span > </span>{
<span > </span>s=s+leaf_char[k];
<span > </span>j=j+code_length;
<span > </span>}
<span > </span>}
<span > </span>}
<span > </span>return s;
<span > </span>}
};
string huffmancoding(const string &src)
{
<span > </span>cout << "=========== Huffman coding ===========" << endl;
<span > </span>cout << "Input string : " << src << endl;
<span > </span>string destCode;
<span > </span>/// 在此处添加编码代码,输入为src,输出为destCode
<span > </span>
<span > </span>int p[26];
<span > </span>char c[26];
<span > </span>c[0]=src[0];
<span > </span> //字符串的各字符不重复地放入c[]
<span > </span>int c_count=1; //数组c[]的数量
<span > </span>for(int j=0;j<src.length();j++)
<span > </span>{
<span > </span>int k=0;
<span > </span>for(k=0;k<c_count;k++) //寻找当前的字符在c[]中是否有记录
<span > </span>{
<span > </span>if(c[k]==src[j]) //有记录则跳出循环 且k=0
<span > </span>{
<span > </span>k=0;
<span > </span>break;
<span > </span>}
<span > </span>}
<span > </span>if(k>0) //在c[]中未找到当前字符
<span > </span>{
<span > </span>c_count++;
<span > </span>c[c_count-1]=src[j];
<span > </span>
<span > </span>}
<span > </span>
<span > </span>}
<span > </span> //计算src中各字符的出现次数 相对应记录于p[]
<span > </span>for(int j=0;j<=c_count;j++)
<span > </span>{
<span > </span>p[j]=0;
<span > </span>for(int h=0;h<src.length();h++)
<span > </span>{
<span > </span>if(src[h]==c[j])
<span > </span>p[j]++;
<span > </span>}
<span > </span>}
<span > </span>
<span > </span>HuffmanTree h_tree;
<span > </span>h_tree.build_tree(p,c,c_count);
<span > </span>cout << "===== Code for each char :" << endl;<span > </span>
<span > </span>destCode=h_tree.turn_string_code(src);<span > </span>
<span > </span>cout << "Coded string : " << destCode << endl;
<span > </span><pre code_snippet_id="314458" snippet_file_name="blog_20140427_1_8226741" name="code" class="cpp"><span style="font-family:Arial, Helvetica, sans-serif;"><span > </span>string destDecode;</span>
/// 此处输出每个字符的编码
/// 在此处添加解码代码,输入为destCode,输出为destDecode
destDecode=h_tree.deCode(destCode);
cout << "Decoded string : " << destDecode << endl;
return destDecode;
}