霍夫曼树编码与译码

#include<iostream>
#include<stdlib.h>
#include<cstring>
using namespace std;
typedef struct hftree{
	int might;
	int parent,lch,rch;
	char data; 
}*tree,node;
typedef char** treecode;
int length;//字符串长度; 
void chushi(tree &hf,int n)//初始话 
{
	hf=new node[2*n];
	for(int i=1;i<=2*n-1;i++)
	{
		hf[i].data='\0';
		hf[i].might=0;
		hf[i].lch=0;
		hf[i].rch=0;
		hf[i].parent=0;
	}
} 
void select(tree T,int n,int &s1,int &s2)//找出权值最小的两个; 
{
    int k,m;
	k=m=1000000; 
		for(int j=1;j<=n;j++)
		{
			if(m>T[j].might&&T[j].parent==0)
			{
				m=T[j].might;
				s1=j;			
			}			  
        }               		
		for(int i=1;i<=n;i++)
		{   
			if(i!=s1&&k>T[i].might&&T[i].parent==0)
			{
				k=T[i].might;
				s2=i;				
			}
		}
} 
void hftree(tree &hf,int n)//创建霍夫曼树 
{
	int s1,s2;
	if(n<=1) return;
	int m=2*n-1; 
	for(int i=n+1;i<=m;++i)
	{
		select(hf,i-1,s1,s2);
		hf[s1].parent=i;
		hf[s2].parent=i;
		if(s1<=s2){
		    hf[i].lch=s1;
		    hf[i].rch=s2;
		}
		else{
			hf[i].lch=s2;
		    hf[i].rch=s1;
		}				
		hf[i].might=hf[s1].might+hf[s2].might;				
	}	
}
void codetree(tree hf,treecode &hc,int n)//获取字符的编码值  
{ 	
    int m,p;  		
	hc=new char*[n+1]; //指针数组; 	
    char *cd=new char[n];	//存放编码	   
    cd[n-1]='\0';		
    for(int i=1;i<=n;i++)
    {
    	int start=n-1;
    	m=i;
		p=hf[i].parent;
    	while(p!=0)
    	{
    		--start;
    		if(hf[p].lch==m)
    		{
    			cd[start]='0';
			}
			else
			    cd[start]='1';
			m=p;
		    p=hf[p].parent;			    
		}
		hc[i]=new char[n-start];
    	strcpy(hc[i],&cd[start]);    	   	
	}
	delete []cd;		
}
void input(tree &hf,int &n,char *date)//输入字符串 
{ 
	char *a=date;
	int length_1;
	int num[256]={0};
	int b[256];
	int c[256];
	cout<<"输入字符串:"; 
	getchar();
	gets(a);
	length_1=strlen(a);
	for(int i=0;i<length_1;i++)
	{
		num[(int)a[i]]++;//统计每个字符的权值 
	}
	n=0;
	for(int i=0;i<256;i++)
	{
		if(num[i]!=0)
		{   
		   	b[n]=num[i]; 
		   	c[n]=(char)i; 
			++n;
		}
	}
	hf=new node[2*n];
	for(int i=1;i<=2*n-1;i++)
	{
		hf[i].data='\0';
		hf[i].might=0;
		hf[i].lch=0;
		hf[i].rch=0;
		hf[i].parent=0;
	}
	for(int i=1;i<=n;i++)
	{
		hf[i].might=b[i-1];
		hf[i].data=c[i-1];
	}	
} 
int weizhi(tree hf,char *q,int n) //获取字符在树中的位置 
{
	char *date=q;
    	for(int j=1;j<=n;++j)
    	{
    		if(*date==hf[j].data)
    			return j;
		} 
}
void bianmachar(tree hf,char *q,treecode &result,int n)//对字符串编码 
{
	char *date=q;
	char *cd;
    int m,p;	
	result=new char * [length+1];//存放每个字符的编码值; 	
    cd=new char[n];
    cd[n-1]='\0';   
    for(int i=0;i<length;++i)
    {   
    	m=weizhi(hf,&date[i],n);//获取每个字符在树中的位置 
    	int start=n-1; 
		p=hf[m].parent;
    	while(p!=0)
    	{
    		--start;
    		if(hf[p].lch==m)
    		{
    			cd[start]='0';
			}
			else
			    cd[start]='1';
			m=p;
		    p=hf[p].parent;			    
		}		
		result[i+1]=new char[n-start];
		strcpy(result[i+1],&cd[start]); 			   	   	
	}
	delete cd;		
}	
void chu(tree hf,treecode hc,treecode result,int n)//输出编码 
{
	int m=2*n-1;
	cout<<"每个字符在树中的位置"<<endl; 
	for(int i=1;i<=m;i++)
	{
		cout<<i<<" "<<hf[i].data<<" "<<hf[i].might<<" "<<hf[i].parent<<" "<<hf[i].lch<<" "<<hf[i].rch<<endl;
	}
	cout<<"每个字符的编码"<<endl; 
	for(int i=1;i<=n;i++)
	{
		cout<<hf[i].data<<" "<<hc[i]<<endl;	
	} 
	cout<<"对字符串的编码:";
	for(int j=1;j<=length;j++)
	{
		cout<<result[j];
	}
}
void input_(tree &hf,int &n) //输入每个字符和对应的权值
{
	cout<<"输入字符和对应的权值"<<endl; 
	for(int i=1;i<=n;i++)
	{
		cin>>hf[i].data;
		cin>>hf[i].might;
	}	
} 
void Decodehf(tree hf,char *m,int n)//译码 
{
	char*date=m;//编码字符串
	int LL=strlen(date);//编码字符串长度  
	char data[100];//解码字符串; 
	int p=2*n-1;//获取根节点的位置; 
	int j=0;//头指针 
	for(int i=0;i<length;i++)
	{										
			if(date[i]=='0')
	 		p=hf[p].lch;
			else if(date[i]=='1')
			p=hf[p].rch;				
			if(hf[p].lch==0&&hf[p].rch==0)
			{			
				data[j]=hf[p].data;
				p=2*n-1;
				++j;			
			} 		
}
	cout<<"对应编码:"; 
	for(int k=0;k<j;k++)
	{
		cout<<data[k];
	}
	cout<<endl;
 } 
 void Xmb()//界面 
{	cout<<"\t\t\t------------------------------------------"<<endl;
 	cout<<"\t\t\t|************霍夫曼编码译码**************|"<<endl;
 	cout<<"\t\t\t|----------------------------------------|"<<endl;
 	cout<<"\t\t\t|********1.对字符串进行编码译码**********|"<<endl; 
	cout<<"\t\t\t|----------------------------------------|"<<endl;
 	cout<<"\t\t\t|********2.输入字符的权值编码译码********|"<<endl;
 	cout<<"\t\t\t------------------------------------------"<<endl;
}
int main()
{
	char a;
	char date_1[100];//输入字符串统计权值 
	char date_2[100];//需要要编码的字符串 
	char date_3[100];//存储译码的字符串
	tree hf; //hfm树 
	treecode hc;//存储每个字符的译码 
	treecode result;//存放译码的字符串 
	int n;//拥有权值的字符个数 	
	while(1)
	{	
		Xmb();
		cout<<"输入相应命令:"; 
		cin>>a;
		switch(a)
		{
			case '1':	
					input(hf,n,date_1); 
					hftree(hf,n);//创建霍夫曼树 
					codetree(hf,hc,n);//每个字符的编码 
					cout<<"输入需要编码的字符串:";
					gets(date_2);
					length=strlen(date_2);
					bianmachar(hf,date_2,result,n);//字符串的编码 					
					chu(hf,hc,result,n);
					cout<<endl;
					cout<<"输入需要译码的编码:" ; 
					gets(date_3);
					Decodehf(hf,date_3,n);
					break;		
			case '2':			
					cout<<"输入字符个数:";
					cin>>n;
					chushi(hf,n);//对霍夫曼树初始化 
					input_(hf,n);//输入字符和对应的权值 
					hftree(hf,n);
					codetree(hf,hc,n);
					cout<<"输入需要编码的字符串:";
					getchar();
					gets(date_2);
					length=strlen(date_2);
					bianmachar(hf,date_2,result,n);
					chu(hf,hc,result,n);
					cout<<endl;
					cout<<"输入需要译码的编码:" ; 
					gets(date_3);
					Decodehf(hf,date_3,n);
					break;
			case '0':
					exit(0);						
		}	
	}

}

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值