• 哈夫曼编码与译码


    问题:事情总是这样,当你明白时,很简单,但当你不会时,又好像觉得自己怎么那么笨。。。

    huffman算法关键是选择两个最小的数时不要弄错了。

    刚开始看时,真的很吃力,都不敢相信自己居然把huffman译码也做出来了。

    代码:

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    
    int s1,s2;
    typedef struct huffmanNode
    {
    	int weight;
    	int parent;
    	int lchild;
    	int rchild;
    }*HuffmanTree;
    
    typedef struct weight
    {
    	char c;
    	int wt;
    }*wt;
    typedef char** HuffmanCode;
    void select(HuffmanTree ht,int i);
    void CreateHT(HuffmanTree &ht,HuffmanCode &code,wt w,int n)   //编码
    {
    	int m,i,j,start;
    	char *cd;
    	if(n<1)
        return;
    	m=2*n-1;
    	ht=(HuffmanTree)malloc((m)*sizeof(struct huffmanNode));
    	for(i=0;i<n;i++)
    	{
    		ht[i].lchild=0;
    		ht[i].rchild=0;
    		ht[i].parent=0;
    		ht[i].weight=w[i].wt;
    	}
    	for(j=i;j<m;j++)
    	{
    		ht[j].lchild=0;
    		ht[j].rchild=0;
    		ht[j].parent=0;
    		ht[j].weight=0;
    	}
    	for(i=n;i<m;i++)                    //构造哈夫曼树
    	{
    		select(ht,i-1);
    		ht[s1].parent=i;
    		ht[s2].parent=i;
    		ht[i].lchild=s1;
    		ht[i].rchild=s2;
    		ht[i].weight=ht[s1].weight+ht[s2].weight;
    	}
    	code=(HuffmanCode)malloc(n*sizeof(char*));
    	cd=(char *)malloc(n*sizeof(char));
    	for(int k=0;k<n;k++)
    	{
             start=0;
    		 for(int p=k,f=ht[k].parent;f!=0;p=f,f=ht[f].parent)
    		 {
    			 if(ht[f].lchild==p)cd[start++]='0';
    			 else cd[start++]='1';
    
    		 }
    		 cd[start]='\0';
    		 code[k]=(char*)malloc((start)*sizeof(char));
    		 strcpy(code[k],cd);
    		 
    		
    	}
    
    	 free(cd);
    }
    
    void select(HuffmanTree ht,int i)
    {
    	int j,t,k;
    	for(j=0;j<=i;j++)
    	{
    		if(ht[j].parent==0)
    		{
    			s1=j;
    			break;
    		}
    	}
    	for(t=j+1;t<=i;t++)
    	{
    		if(ht[t].parent==0)
    		{
    			s2=t;
    			break;
    		}
    	}
    	for(k=0;k<=i;k++)
    	{
    		if((ht[k].weight<ht[s1].weight)&&(k!=t)&&(ht[k].parent==0))
    		{
    			s1=k;
    		}
    	}
    	for(k=0;k<=i;k++)
    	{
    		if((ht[k].weight<ht[s2].weight)&&(k!=s1)&&(ht[k].parent==0))  //容易出错,看出来了吗?
    		{
    			s2=k;
    		}
    	}
    }
    
    void TransHT(HuffmanTree ht,HuffmanCode code,int n,wt w)    //译码
    {
    	int temp;
    	int len;
    	int f;
    	int j,m;
    	for(int t=0;t<(2*n-1);t++)
    	{
    		if(ht[t].parent==0)
    		{
    			temp=t;
    			break;
    		}
    	}
    	for(j=0;j<n;j++)
    	{
    		len=strlen(code[j]);
    		f=temp;
    		for(int k=len-1;k>=0;k--)
    		{
    			if(code[j][k]=='0')
    				f=ht[f].lchild;
    			else
    				f=ht[f].rchild;
    		}
    		for(m=0;m<n;m++)
    		{
    			if(ht[f].weight==w[m].wt)
    			{
    				cout<<code[j]<<": "<<w[m].c<<endl;
    				break;
    			}
    		}
    	}
    }
    int main()
    {
    	HuffmanTree ht;
    	HuffmanCode code;
    	wt w;
    	int n;
    	cout<<"请输入字符个数:";
    	cin>>n;
    	w=(wt)malloc(n*sizeof(struct weight));
    	cout<<"请输入各字符的权重:"<<endl;
    	for(int i=0;i<n;i++)
    	{
    		cin>>w[i].c>>w[i].wt;
    	}
    	cout<<"创建哈夫曼树:"<<endl;
    	CreateHT(ht,code,w,n);
    	cout<<"输出哈夫曼编码:"<<endl;
    	for(int i=0;i<n;i++)
    	{
    		cout<<w[i].c<<"  ";
    		cout<<code[i];
    		cout<<endl;
    	}
    	cout<<"译码结果为:"<<endl;
    	TransHT(ht,code,n,w);
    	return 0;
    }
    

    运行结果:

  • 相关阅读:
    从0开始的Python学习013编写一个Python脚本
    Spring Cloud Eureka基本概述
    RocketMQ入门案例
    Quartz使用记录总结
    Spring Boot 1.5升级2.1 主要问题汇总
    Eureka客户端注册多网卡下IP选择问题
    Spring Security之动态配置资源权限
    代码规范问题
    Spring Security + OAuth系统环境搭建(一)
    Java并发编程之AQS
  • 原文地址:https://www.cnblogs.com/xshang/p/3053363.html
Copyright © 2020-2023  润新知