别人的课程设计:哈夫曼树

#include<stdlib.h>
#include<string.h>
#include<stdio.h>


#define MAX_Node_num 30


typedef struct
{
	char elem;
	unsigned int weight;
	unsigned int parent,lc,rc;

}HTNode,*HuffmanTree;

typedef char ** HuffmanCode;

typedef struct weight
{
	char elem;
	unsigned int m_weight;
}Weight;

int f,start,c,s1,s2;

//横向打印,将树打横放置。。。
//*************打印哈夫曼树函数****************
int numb=0 ;

void coprint(HuffmanTree start,HuffmanTree HT)   //start=ht+26这是一个递归算法
{

	if(start!=HT)
	{
		numb++;       //number=0 该变量为已被声明为全局变量
		coprint(HT+start->rc,HT);             //递归先序遍历

		printf("%*d\n",5*numb,start->weight);
		//if(start->rchild==0) cout<<info[start-HT-1]<<endl;
		printf("%d",start->weight) ;
		coprint(HT+start->lc,HT);
		numb--;
	}
}
void Tree_printing(HuffmanTree HT,int num)
{
	HuffmanTree p;
	p=HT+2*num-1;                 //p=HT+26
	printf("下面打印赫夫曼树\n") ;
	coprint(p,HT);                //p=HT+26
	printf("打印工作结束\n") ;
}


void Select(HuffmanTree HT,int i,int &s1,int &s2)
{ //在建立哈夫曼树的所有结点中选择权值最小的两个结点存放在s1,s2中
	int j,k=1;
	while(HT[k].parent!=0)
		k++;
	s1=k;
	for(j=1;j<=i;++j)
		if(HT[j].parent==0&&HT[j].weight<HT[s1].weight)
			s1=j;
		k=1;
		while(HT[k].parent!=0||k==s1)
			k++;
		s2=k;
		for(j=1;j<=i;++j)
			if(HT[j].parent==0&&HT[j].weight<HT[s2].weight&&j!=s1)
				s2=j;
}

void HuffmanCoding(HuffmanTree &HT ,HuffmanCode &HC ,Weight *w ,int n)
{
	int m,i;

	m=2*n-1;
	if(m<=1) return ;
	HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));
	for (i=1; i<=n; i++)
	{ //初始化
		HT[i].elem=w[i-1].elem;
		HT[i].weight=w[i-1].m_weight;
		HT[i].parent=0;
		HT[i].lc=0;
		HT[i].rc=0;
	}
	for (i=n+1; i<=m; i++)
	{ //初始化
		HT[i].weight=0;
		HT[i].parent=0;
		HT[i].lc=0;
		HT[i].rc=0;
	}

	for(i=n+1;i<=m;++i)//建立哈夫曼树过程
	{
		Select(HT,i-1,s1,s2);

		HT[s1].parent=i;
		HT[s2].parent=i;
		HT[i].lc=s1;
		HT[i].rc=s2;
		HT[i].weight=HT[s1].weight+HT[s2].weight;

	}
	printf("   i     weight   parent     lc      rc      \n") ;
	for (i=1; i<=m; i++)
		printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight,HT[i].parent,HT[i].lc, HT[i].rc);

	HC=(HuffmanCode)malloc((n+1)*sizeof(char*)) ;
	char *cd ;
	cd=(char*)malloc(n*sizeof(char)) ;
	cd[n-1]='\0';

	for(i=1;i<=n;++i)
	{
		start=n-1;
		for(c=i,f=HT[i].parent ;f!=0;c=f,f=HT[f].parent)
			if(HT[f].lc==c)
				cd[--start]='0';
			else cd[--start]='1';
			HC[i]=(char*)malloc((n-start)*sizeof(char));
			strcpy(HC[i],&cd[start]);
	}
	free (cd);
}
void OutputHuffman(HuffmanTree HT,int n)
{
	char ch;
	printf("请输入编码\n");
	int j=2*n-1;
	getchar();
	ch=getchar();


	while(ch!='\n')
	{
		if(ch=='0')
		{
			j=HT[j].lc;

		}
		else if(ch=='1')
		{
			j=HT[j].rc;

		}
		else
		{
			printf("error\n");
		}
		if(HT[j].lc==0&&HT[j].rc==0)
		{
			printf("%c",HT[j].elem);
			j=2*n-1;
		}

		ch=getchar();
	}
}
void OutputHuffmanCode(HuffmanTree HT,HuffmanCode HC,int n)
{
	int i;

	printf("\nnumber---element---weight---huffman code\n");
	for(i=1;i<=n;i++)
		printf("  %d        %c         %d        %s\n",i,HT[i].elem,HT[i].weight,HC[i]);


}
int  main()
{
	HuffmanTree HT;
	HuffmanCode HC,t;

	Weight *w;
	char c,ch;		// the symbolizes;
	int i,n,j;      // the number of elements;
	int wei;		// the weight of a element;

	printf("请输入构建哈夫曼树的结点数:" );
	scanf("%d",&n);
	w=(Weight *)malloc(n*sizeof(Weight));
	for(i=0;i<n;i++)
	{
		//cout<<"请输入第"<<i+1<<"个结点编号及其权值(如a 100):"<<endl;
		printf("请输入结点编号及其权值(如a 100):" );
		scanf("%1s%d",&c,&wei);
		w[i].elem=c;
		w[i].m_weight=wei;
	}

	HuffmanCoding(HT,HC,w,n);
	OutputHuffmanCode(HT,HC,n);
	t=(HuffmanCode)malloc((n+1)*sizeof(char*));
	FILE *fp1;

	if((fp1=fopen("tra.txt","w"))==NULL)
	{
		printf("无法新建文件\n");
		exit(0);
	}

	Tree_printing(HT,n) ;

	ch=getchar();
	printf("输入要输入文件的内容#号结束:");
	ch=getchar();
	while(ch!='#')
	{
		fputc(ch,fp1);
		ch=getchar();
	}
	fclose(fp1);

	if((fp1=fopen("tra.txt","r"))==NULL)
	{

		printf("无法打开文件\n");
		exit(0);
	}
	int k=1;
	while(!feof(fp1))
	{
		ch=fgetc(fp1);
		printf("\n");
		for(j=1;j<=n;j++)
		{
			if(ch==HT[j].elem )
			{
				printf("%s",HC[j]);
				t[k]=(char*)malloc((n)*sizeof(char));
				//putchar(HT[j].elem);
				t[k]=HC[j];

				k++;}

		}
	}
	fclose(fp1);
	FILE *fp;
	if((fp=fopen("yima.txt","w"))==NULL)
	{

		printf("无法打开文件\n");
		exit(0);
	}
	for(i=1;i<n+1;i++)
	{
		fputs(t[i],fp);
	}
	fclose(fp);

	for(j=1;j<k;j++)
		printf("%s",t[j]);

	printf("\n");
	OutputHuffman(HT,n);

	return 0 ;
}





你可能感兴趣的:(别人的课程设计:哈夫曼树)