Huffman tree
//输出Huffman编码
本程序实现了如何将一串字符串输出为Huffman编码
VER || 1.0
DATE || 15/11/2017
AUTHER || WUD
比输入字符串agdfaghdabsba
通过字符串的处理可以知道其中每个字符出现的次数
字符a出现了4次
字符g出现了2次
字符d出现了2次
字符b出现了2次
字符f出现了1次
字符h出现了1次
字符s出现了1次
然后构建Huffman树,得到每个字符对应的Huffman编码
字符串的每个字符串的huffman编码为:
a 10
g 011
d 110
b 111
f 000
h 001
s 010
最后得到整个字符串的Huffman编码
整个字符串的Huffman编码为:
10011110000100110011101011101011110
#include<iostream>
#include<string>
#include <windows.h>
#include<stdio.h>
using namespace std;
/*
--------------------------
VER || 1.0
DATE || 15/11/2017
AUTHER || WUD
--------------------------
*/
struct huffTree{
int parent;
int lchild;
int rchild;
int weight;
string flag;
};
struct Lowest_Node{
char ch;
int ch_num;
};
void ShowProgram()
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
int j;
for(j=0; j<27; j++){
printf("-");
Sleep(1);}
printf("\n");
printf("VER || 1.0\n");
printf("DATE || 15/11/2017\n");
printf("AUTHER || WUD\n");
for(j=0; j<27; j++){
printf("-");
Sleep(1);
}
printf("\n");
Sleep(200);
}
void coding(int length, huffTree tree[], int n, int &a, int &b){
int i;
int r,s;
r=s=length;
for(i=0;i<n;i++){
if((tree[i].weight<r)&&(tree[i].parent==-1)){
r=tree[i].weight;
a=i;
}
}
for(i=0;i<n;i++){
if((tree[i].weight<s)&&(i!=a)&&(tree[i].parent==-1)){
s=tree[i].weight;
b=i;
}
}
}
void frequency(string str){
int length = str.length(); //长度
Lowest_Node *node=new Lowest_Node[length]; //声明最0节点
int i,j; //循环因子
for(i=0;i<length;i++){
node[i].ch_num = 0; //初始化频度
}
int char_type_num = 0; //初始为0种字符
for(i=0;i<length;i++){ //循环整个字符串
for(j=0;j<char_type_num;j++){
if(str[i]==node[j].ch||(node[j].ch>='a'&&node[j].ch<='z'&&str[i]+32==node[j].ch))
break;}
if(j<char_type_num){node[j].ch_num++;}
else{
if(str[i]>='A'&& str[i]<='Z')
node[j].ch=str[i]+32;
else node[j].ch = str[i];
node[j].ch_num++;
char_type_num++;
}
}
//按频度从大到小排序
for(i=0;i<char_type_num;i++){
for(j=i;j<char_type_num;j++){
if(node[j].ch_num<node[j+1].ch_num){//如果前一个小于后一个,交换
int temp; //临时频度
char ch_temp; //临时字符
temp=node[j].ch_num;
ch_temp=node[j].ch;
node[j].ch_num=node[j+1].ch_num;
node[j].ch=node[j+1].ch;
node[j+1].ch_num=temp;
node[j+1].ch=ch_temp;
}
}
}
for(i=0;i<char_type_num;i++){ //打印字符频度
cout<<"字符"<<node[i].ch<<"出现了"<<node[i].ch_num<<"次"<<endl;}
huffTree *huff = new huffTree[2*char_type_num-1];//声明需位于确定char_type_num值后
huffTree temp;
string *code = new string[2*char_type_num-1];
for(i=0;i<2*char_type_num-1;i++){ //节点初始化
huff[i].parent=-1;
huff[i].lchild=-1;
huff[i].rchild=-1;
huff[i].flag=-1;
}
for(j=0;j<char_type_num;j++){ //将排序后的第0级节点权重赋值给树节点
huff[j].weight = node[j].ch_num;
}
int min1,min2;
for(int k=char_type_num;k<2*char_type_num-1;k++){ //赋值0级以上的节点
coding(length,huff,k,min1,min2);
huff[min1].parent=k;
huff[min2].parent=k;
huff[min1].flag="0";
huff[min2].flag="1";
huff[k].lchild=min1;
huff[k].rchild=min2;
huff[k].weight=huff[min1].weight+huff[min2].weight;
}
for(i=0;i<char_type_num;i++){
temp = huff[i];
while(1){
code[i]=temp.flag+code[i];
temp =huff[temp.parent];
if(temp.parent==-1)break;
}
}
cout<<"字符串的每个字符串的huffman编码为:"<<endl;
for(i=0;i<char_type_num;i++){
cout<<node[i].ch<<" "<<code[i]<<endl;
}
cout<<"整个字符串的Huffman编码为:"<<endl;
for(i=0;i<length;i++){
for(j=0;j<char_type_num;j++){
if(str[i]==node[j].ch)
cout<<code[j];
}
}
//释放内存
delete[] node;
node=NULL;
delete[] huff;
huff=NULL;
delete[] code;
code = NULL;
}
int main(){
ShowProgram();
int length=0; //字符串长度;
string str; //目标字符串;
cout<<"请输入字符串:";
cin>>str;
frequency(str); //求各个字符串的频度
return 0 ;
}