#include<bits/stdc++.h>
using namespace std;
int b[26]={0};
int bb[26]={0};
int kk;
struct node{
int w;
int p,l,r;
};
set <node> se;
string Open(char* s){
string str = "";
ifstream op;
char ch;
op.open(s);
while(!op.eof()){
op>>ch;
str+=ch;
//cout<<ch;
}
//cout<<endl;
op.close();
return str;
}
void Count(string str){
kk = 0;
int ls = str.size();
for(int i=0;i<ls-1;i++){//处理掉多出来的一个字符
str[i] = tolower(str[i]);
b[str[i]-'a']++;
}
for(int i=0;i<26;i++){
if(b[i]){
char c = i+'a';
cout<<c<<':'<<b[i]<<endl;//b[i]即为权值
bb[kk++] = b[i];
}
}
// for(int i=0;i<k;i++){
// cout<<bb[i]<<endl;
// }
}
///选择两个parent为0,且weight最小的结点s1和s2
void Select(node* &ht,int n,int& a,int& b)
{
int i,min;
for(i=1; i<=n; i++){
if(ht[i].p==0){
min=i;
break;
}
}
for(i=1; i<=n; i++){
if(ht[i].p==0){
if(ht[i].w<ht[min].w)
min=i;
}
}
a=min;
for(i=1; i<=n; i++){
if(ht[i].p==0 && i!=a){
min=i;
break;
}
}
for(i=1; i<=n; i++){
if(ht[i].p==0 && i!=a){
if(ht[i].w<ht[min].w)
min=i;
}
}
b=min;
}
void CreateTree(node* &HT,int n){
int k=0;
if(n<=1) return;
int m = 2*n-1;
HT = new node[m+1];
for(int i=1;i<=m;i++){
HT[i].p = 0, HT[i].l = 0, HT[i].r = 0;
}
for(int i=1;i<=n;i++){
HT[i].w = bb[k++];
}
printf("\n哈夫曼树为: \n");
int s1,s2;
for(int i=n+1; i<=m; i++){
Select(HT,i-1,s1,s2);
HT[s1].p=i;
HT[s2].p=i;
HT[i].l=s1;
HT[i].r=s2;
HT[i].w=HT[s1].w+HT[s2].w;
printf("%d (%d, %d)\n",HT[i].w,HT[s1].w,HT[s2].w);
}
printf("\n");
}
void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n)
{
char *cd; //定义的存放编码的空间
int a[100];
int i,start,p,w=0;
unsigned int c;
hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); //分配n个编码的头指针
cd=(char *)malloc(n*sizeof(char)); //分配求当前编码的工作空间
cd[n-1]='\0'; //从右向左逐位存放编码,首先存放编码结束符
for(i=1; i<=n; i++) //求n个叶子结点对应的哈夫曼编码
{
a[i]=0;
start=n-1; //起始指针位置在最右边
for(c=i,p=(*ht)[i].parent; p!=0; c=p,p=(*ht)[p].parent) //从叶子到根结点求编码
{
if( (*ht)[p].LChild==c)
{
cd[--start]='1'; //左分支标1
a[i]++;
}
else
{
cd[--start]='0'; //右分支标0
a[i]++;
}
}
hc[i]=(char *)malloc((n-start)*sizeof(char)); //为第i个编码分配空间
strcpy(hc[i],&cd[start]); //将cd复制编码到hc
}
free(cd);
for(i=1; i<=n; i++)
printf(" 权值为%d的哈夫曼编码为:%s\n",(*ht)[i].weight,hc[i]);
for(i=1; i<=n; i++)
w+=(*ht)[i].weight*a[i];
printf(" 带权路径为:%d\n",w);
}
int main(){
char* s = "C:\\Users\\Answer\\Desktop\\实验6-哈夫曼编码算法的实现\\SourceFile.txt";
//cout<<Open(s)<<endl;//str 比原串多一个H字符
string str = Open(s);
cout<<str<<endl<<endl;
Count(str);
node* HT;
CreateTree(HT,kk);
CrtHuffmanCode(&HT,&HC,n);
return 0;
}
完成版
猜你喜欢
转载自blog.csdn.net/qq_41333844/article/details/83624603
今日推荐
周排行