数据结构课程设计-12月28日

今天进行了一天的项目设计与编码工作,从早上8点持续到中午1点。开始时对昨晚的设计进行了调整,并遇到了C语言生疏的问题。在解决文件操作和哈夫曼树相关困难后,完成了对原始文件的读取、编码和写入操作。虽然遇到了一些挑战,但通过不断学习和尝试,最终完成了任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

课设是早上8点到中午1点,今天是第一天,比起上学期的课设,这次真的是比较从容淡定。

然而即使这样说,问题还是有的。

首先是对昨天晚上的前期设计做了些改变。

然后因为好久没写C,结果搞的有些都忘,文件操作那块也忘。

最后就是哈夫曼树并没有学习了解掌握,结果就是把老师课件上的代码copy过来。

以下先是今天的成果

#include<stdio.h>
#include<stdlib.h>
#define Max 1024
#define n 30
#define m 2*n-1
#define MAXINT 32767 
typedef struct{
	int weight;
	int parent,Lchild,Rchild;
}HTNode,HuffmanTree[m];

int read(char x[]);				//文件读取
int write(char x[]);			//文件写入
void print(char x[]);			//打印文件内容
void countChar(char x[]);		//统计字符频度,权值放在一个数组中
void CrtHuffmanTree(HuffmanTree ht,int w[ ],int n);			//哈弗曼树的建立
void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n);	//哈弗曼树的编码
void CrtHuffmanTran(HuffmanTree ht,int n);					//哈弗曼树的译码
char souce[Max];					//原文件内容的字符数组存放
char code[Max];					//编码后的字符数组存放
char decode[Max];					//译码后的字符数组存放
int length=0;

typedef struct{				//权值的存放
	int l;
	int x;
}charrr[Max];
charrr[0]={0,0};

typedef char *HuffmanCode[N+1]		//指针数组动态存放每个编码串的头指针
int main(){

}

int read()
{
	FILE *fp=fopen("x.souce","r");		//原文本本件名字x;
	char c;
	int i=0;
	if (fp==NULL)
	{
		printf("Open failed...\n");
		return 0;
	}
	while ((c=getc(fp))!=EOF)
	{
		souce[i]=c;
		i++;
	}							//把读取的数据内容放到souce[]数组中
	fp.close();
	return 1;
}

void write(char name[],char x[])				//写入一个新的文件
{
	FILE *fp=fopen(name,"w");
	if (fp==NULL)
	{
		printf("Open failed...\n");
		return 0;
	}
	fwrite(x,sizeof(char),sizeof(x),fp);
	fclose(fp);
}

void print(char x[]){
	int i=0;
	while (x[i]!='\0')	i++;

	for (int j=0;j<i;j++)
		printf("%s",x);
	printf("\n");
}

void countChar(char x[]){
	int i=0,j;
	while (x[i]!='\0') i++;
	char c;
	if (read())		//读取原文件文件,用遍历统计字符频度算法souce;
	{
		for (j=0;j<=i;j++)
		{
			charrr[souce[j]].id=souce[j];
			charrr[souce[j]].x++;
			length++;
		}
	}			
	//权值放在一个数组中,然而现在权值让在了charrr[].x中
}

void sort(int x[])
{
	int i,j;
	int temp;
	int min,minm;
	for (i=0;i<N;i++)
		for (j=i+1;j<N;J++)
			if (x[i]>x[j])
			{
				temp=x[i];
				x[i]=x[j];
				x[j]=temp;
			}
	min=x[0];
	minm=x[1];
}

void CrtHuffmanTree(HuffmanTree ht,int w[ ],int n){
	countChar();	//获取个字符出现的频度,已放入quan[N];
	n=length;
	for (int i=0;i<n;i++)	w[i]=charrr[i].x;
	int i, s1 , s2, m; 
	m=2*n-1; 
	for(i=1;i<=n;i++) 
	{	
		ht[i].weight=w[i]; 
		ht[i].parent=0; 
		ht[i].lchild=0; 
		ht[i].rchild=0; 
	} 
	for(i=n+1;i<=m;i++) 
	{ 
		ht[i].weight=0;     
		ht[i].parent=0; 
		ht[i].lchild=0; 
		ht[i].rchild=0;
	}
	for(i=n+1;i<=m;i++) 
	{ 
		select(ht,i-1,&s1,&s2);
		ht[i].weight=ht[s1].weight+ht[s2].weight;
		ht[s1].parent=i;      
		ht[s2].parent=i; 
		ht[i].lchild=s1;   
		ht[i].rchild=s2; 
	} 

	CrtHuffmanCode();
	write();		//并将code内容写入新的*.code文件中	
}

void select(HuffmanTree ht, int pos, int *s1, int *s2 )		//Huffman算法实现—选择函数	
{  
	int i, j, m1,m2;  /*m1存放最小权值,s1是m1在数组的下标*/   
	m1=m2=MAXINT; /*m2存放次小权值,s2是m2在数组的下标*/ 
	for(j=1;j<=pos;j++)   
	{   
		if (ht[j].weight<m1 && ht[j].parent==0)  
		{   m2 = m1;     
		*s2=*s1; 
		*s1=j;
		m1 = ht[j].weight; 
		} 
		else  if(ht[j].weight<m2 && ht[j].parent==0)
		{ m2 = ht[j].weight; 
		*s2 = j; 
		} 
	}
		if(*s1>*s2) 
			/*使s1小于s2*/ {   i=*s1;  *s1=*s2;  *s2=i;  }
}
	

void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n)		//哈弗曼树编码算法
{	
		char *cd;
		int start,c,p,i; 
		cd=(char *)malloc(n*sizeof(char)); 
		cd[n-1]='\0'; 
		for(i=1;i<=n;i++) { 
			start=n-1; 
			c=i; 
			p=ht[i].parent; 
			while(p!=0) {    
				--start; 
				if(ht[p].lchild==c) 
					cd[start]='0'; 
				else  
					cd[start]='1'; 
				c=p;  
				p=ht[p].parent; 
			} 
			hc[i]=(char *)malloc((n-start)*sizeof(char)); 
			strcpy(hc[i],&cd[start]);  
		} 
		free(cd);			
		for (int j=0;j<i;j++)
			code[j]=hc[j];				//得hc[]后将编码内容放入code[];
}

void CrtHuffmanTran(HuffmanTree ht,char Code[],int n)//对code[]进行译码	//将译码结果放入decode[1024];//并将decode内容写入新的*.decode文件中
{
	   					
				
	write();		
}

然后,快要断电了,因为和班长讨论概率论问题

明天再总结一天。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值