• 赫夫曼编码


    /* 
       功能Function Description:     赫夫曼编码---正误待验证(调试时候感觉有地方好像出错了)
       开发环境Environment:          DEV C++ 4.9.9.1
       技术特点Technique:
       版本Version:
       作者Author:                   可笑痴狂
       日期Date:                 	 20120803
       备注Notes:                  
       作用:
    		输入大写字母组成的字符串,然后以其出现的次数为权重进行编码
    */
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    
    typedef struct Node
    {
    	unsigned int weight;
    	unsigned int parent,left,right;
    }HTNode,*HuffmanTree;
    typedef char **HuffmanCode;
    
    void HuffmanCoding(int *w,int n,char *s)
    {
    	HuffmanTree HT;
    	HuffmanCode HC;
    	HuffmanTree p;
    	int m,i,j,s1,s2,min1,min2,c,f,start;
    	if(n<1)
    		return;
    	m=2*n-1;
    	HT=new HTNode[m+1];           //0号单元没用
    
    	for(p=HT+1,i=1;i<=n;++i,++p,++w)      //初始化
    	{
    		p->weight=*w;
    		p->parent=0;
    		p->left=0;
    		p->right=0;
    	}
    	for(;i<=m;++i,++p)
    	{
    		p->weight=0;
    		p->parent=0;
    		p->left=0;
    		p->right=0;
    	}
    	for(i=n+1;i<=m;++i)
    	{
    		min1=min2=0x7fffffff;
    		//在HT[1,2,.....i-1]中选择parent为0且weight值最小的两个结点,其序号分别为s1、s2
    		for(j=1;j<i;++j)
    		{
    			if(HT[j].parent==0&&min1>HT[j].weight)
    			{
    				min1=HT[j].weight;
    				s1=j;
    			}
    		}
    		HT[s1].parent=i;
    		for(j=1;j<i;++j)
    		{
    			if(HT[j].parent==0&&min2>HT[j].weight)
    			{
    				min2=HT[j].weight;
    				s2=j;
    			}
    		}
    		HT[s2].parent=i;
    		HT[i].left=s1;
    		HT[i].right=s2;
    		HT[i].weight=HT[s1].weight+HT[s2].weight;
    	}
    
    	//从叶子节点到根逆向求每个字符的赫夫曼编码
    	HC=new char*[n+1];     //分配n个字符编码的头指针向量
        char* cd=new char[n];            //分配求编码的工作空间
    	cd[n-1]='\0';
    	for(i=1;i<=n;++i)          //逐个字符求其编码
    	{
    		start=n-1;         //编码结束符标志
    		for(c=i,f=HT[i].parent;f;c=f,f=HT[f].parent) //从叶子到根逆向求编码
    			if(HT[f].left==c)
    				cd[--start]='0';
    			else
    				cd[--start]='1';
    		HC[i]=new char[n-start];
    		strcpy(HC[i],&cd[start]);
    	}
    	delete cd;
    	for(i=0;i<n;++i)       //输出编码
    		cout<<s[i]<<": "<<HC[i+1]<<endl;
    }
    
    int main()
    {
    	char s[1000];
    	int i,j;
    	int weight[27];
    	/*
    	HuffmanTree HT;
    	HuffmanCode HC;
    	*/
    	cout<<"请输入字符串(大写字母):"<<endl;
    	while(cin>>s)
    	{
    		memset(weight,0,sizeof(weight));
    		int len=strlen(s);
    		for(i=0;i<len;++i)
    			++weight[s[i]-'A'];
    		for(i=0,j=0;i<26;++i)    //去掉没有出现过的字母,将字母和权值都压缩存储到原来的空间中
    			if(weight[i])
    			{
    				s[j]=i+'A';
    				weight[j++]=weight[i];
    			}
    		cout<<"赫夫曼编码为:"<<endl;
    		HuffmanCoding(weight,j,s);
    		cout<<"请输入字符串(大写字母):"<<endl;
    	}
    	return 0;
    }
    
    功不成,身已退
  • 相关阅读:
    D. Beautiful Array
    C. Magic Ship Educational Codeforces Round 60 (Rated for Div. 2)
    CCPC-Wannafly Winter Camp Day3 小清新数论(莫比乌斯反演反演加杜教筛)
    杜教筛
    Algorithms Weekly 3
    Algorithms Weekly 2
    Algorithms Weekly 1
    KNN算法实现数字识别
    2019总结
    2019 Google Kickstart Round H
  • 原文地址:https://www.cnblogs.com/dongsheng/p/2621269.html
Copyright © 2020-2023  润新知