哈夫曼编码与译码

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

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;

}

运行结果:

哈夫曼编码与译码

 

你可能感兴趣的:(编码)