霍夫曼树编码实现

#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 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 num[256]={0};
	int b[256];
	int c[256];
	length=strlen(a);
	for(int i=0;i<length;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 &hc,treecode &result,int n)//对字符串编码 
{
	char *date=q;
	char *cd;
    int m,p;	
	result=new char * [length+1];//存放每个字符的编码值; 	
	hc=new char*[n+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,treecode hc1,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<<" "<<hc1[i]<<endl;	
	} 
	cout<<"对字符串的编码"<<endl;
	for(int j=1;j<=length;j++)
	{
		cout<<result[j];
	}
}

int main()
{
	char date[50];//字符串最大值为50; 
	tree hf;
	treecode hc;
	treecode hc1;
	treecode result;
	int n;
	cout<<"输入字符串:";
	gets(date); 
	input(hf,n,date);
	hftree(hf,n);
	codetree(hf,hc1,n);
	bianmachar(hf,date,hc,result,n);
	chu(hf,hc,result,hc1,n);
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值