学生信息排序(基于文件)

#include<stdio.h>
#include<stdlib.h>
typedef struct student{
  char number[20];
  int score;
  int location;
  int num;
  char name[10];
}student;
typedef struct{
   student *base;
   int num;
}Message;
void Scan(student *p,int num)
{
		FILE *fp;
		int i;
		if ((fp=fopen("e:\\student.dat","wb"))==NULL)
		{
			printf("无法打开\n");
			exit(1);
		}
		p++;
		for (i=1;i<=num;i++)
		{
		scanf("%s",p->name);
		getchar();
		scanf("%s",p->number);
		getchar();
		scanf("%d",&p->score);
		p->location=i;
		p->num=0;
			fwrite(p,sizeof(student),1,fp);
		p++;
		}
		fclose(fp);
}
void Print(student *r,int num)
{
    FILE *fp;
	int i;
	if ((fp=fopen("e:\\student.dat","rb"))==NULL)
	{
	   printf("无法打开文件:\n");
		exit(1);	
	}
	r++;
	for (i=1;i<=num;i++)
	{
		fread(r,sizeof(student),1,fp);
	printf("原数据为:\n");
		printf("第%d个学生的信息是%s %s %d %d\n",r->location,r->name,r->number,r->score,r->num);
		r++;
	}
	fclose(fp);
}
void Creat(Message &s)
{
	printf("请输入学生数量:\n");
	scanf("%d",&s.num);
     s.base=(student*)malloc((s.num+1)*sizeof(student));
	 printf("请按照姓名、学号、成绩输入学生信息:\n");
		Scan(s.base,s.num);
}

void Rank(Message s)
{
	int i=1,count=1,c=1;
	s.base[i++].num=count;
	    while (i<=s.num)
		{
		    if (s.base[i-1].score!=s.base[i].score)
			{
				count+=c;
				c=1;
				s.base[i].num=count;
				i++;
			}
			else
			{
			  while (i<=s.num&&s.base[i-1].score==s.base[i].score)
			  {
				  c++;
				s.base[i].num=s.base[i-1].num;
				i++;
			  }
			}
		}
}

void Sort1(Message &s)
{
	int i,j;
	for (i=2;i<=s.num;i++)
		if (s.base[i].score>s.base[i-1].score)		//前i个数据已经有序,新添地往前比较,放在相应位置
	{
	   s.base[0]=s.base[i];							//0位置存放当前的大元素
	   s.base[i]=s.base[i-1];
	   for (j=i-2;j>=0&&s.base[0].score>s.base[j].score;j--)		//依次跟以前排好序的元素比较
		   s.base[j+1]=s.base[j];
	   s.base[j+1]=s.base[0];			//插入合适位置
	}
		Rank(s);
}

void Sort2(Message &s)
{
	int i,j;
	int flag=1;
	for (i=1;i<s.num;i++)
	{
		flag=0;
		for (j=s.num-1;j>=i;j--)
		if (s.base[j+1].score>s.base[j].score)
		{
		    s.base[0]=s.base[j+1];
			s.base[j+1]=s.base[j];
			s.base[j]=s.base[0];		
			flag=1;				//在对i的循环中如果没有换位置的,就说明已经排好序了,每个相邻的元素之间都排好了
		}
		if (flag==0)
		   break;
	}
	Rank(s);
}
int Partition(Message &s,int low,int high)    //*
{
	int pivotkey;
	s.base[0]=s.base[low];
	pivotkey=s.base[low].score;
	while (low<high)
	{
		while (low<high&&s.base[high].score<=pivotkey)
		 high--;									//将小值放在关键值的后面
		s.base[low]=s.base[high];						//将high更新
		while (low<high&&s.base[low].score>=pivotkey)	
			low++;								//将大值放在关键值的前面
		s.base[high]=s.base[low];						//将low更新
	}
	s.base[low]=s.base[0];						//保证每次返回比本次关键值的大的一个就行
	return low;
}
void Qsort(Message &s,int low,int high)
{
	int pivotloc;			//位置
	if (low<high)
	{
	   pivotloc=Partition(s,low,high);
	   Qsort(s,low,pivotloc-1);
		Qsort(s,pivotloc+1,high);
	}
}

void Sort3(Message &s)
{
	Qsort(s,1,s.num);
}
void Sort4(Message s)
{
	int i,k,j;
	for (i=1;i<s.num;i++)
	{
	  k=i;
	  for (j=i+1;j<=s.num;j++)
		if (s.base[k].score<s.base[j].score)
		      s.base[k]=s.base[j];
		if (s.base[k].score!=s.base[i].score)
		{
		   s.base[0]=s.base[k];
		   s.base[k]=s.base[i];
		   s.base[i]=s.base[0];
		}
	}
	Rank(s);
}

void Heapadjust(Message &s,int e,int m)
{		//每次调整一个元素,从根开始,在已建好的堆中找到相应位置
	int i;
	student temp;
	temp=s.base[e];
	for (i=2*e;i<=m;i*=2)	//注意for循环的执行,这是由树的特性来确定的
	{
	if (i<m&&s.base[i].score>s.base[i+1].score)   //左大于右
		i++;
	if (temp.score<=s.base[i].score)
		break;
	s.base[e]=s.base[i];		//进行调整,用来不断比较temp的值,以此来确定temp的相应位置
	e=i;
	}
	s.base[e]=temp;
}

void Sort5(Message &s)
{		//本来就存在一个虚拟的,混乱的堆(就是s),在其基础上进行更改
	int i;
	student temp;
	for (i=s.num/2;i>0;i--)
	Heapadjust(s,i,s.num);		//弄好第一个元素,先进行一次排序,按顺序输出是个有序的数组
	for (i=s.num;i>1;i--)
	{
	  temp=s.base[1];				// 关键字最大的与序列最后一个进行交换,然后重新弄堆
	  s.base[1]=s.base[i];
	  s.base[i]=temp;
	  Heapadjust(s,1,i-1);
	}
	Rank(s);
}

void Merge(student a[],student v1[],int i,int m,int n)
{
	int j,k;
	for (j=m+1,k=i;i<=m&&j<=n;k++)
	{									//v1数组存放a数组合并后的序列
	    if (a[i].score<=a[j].score)
			v1[k]=a[j++];
		else	
			v1[k]=a[i++];		
	}
	while (i<=m)
		v1[k++]=a[i++];
	while (j<=n)
		v1[k++]=a[j++];
}
void Msort(student b[],student v2[],int s,int t)
{
	int m;
	student c[100];
	if (s==t)			
		v2[s]=b[s];
	else
	{
	    m=(s+t)/2;
		Msort(b,c,s,m);			//先进行拆分,然后再合并
		Msort(b,c,m+1,t);
		Merge(c,v2,s,m,t);
	}
}
void Sort6(Message &s)
{
   Msort(s.base,s.base,1,s.num);
   Rank(s); 
}

void Put(Message s)
{
   int i;
   printf("学生信息从左往右依次为学生的位置、姓名、学号、成绩、排名:\n");
  for (i=1;i<=s.num;i++)
			printf("第%d个学生的信息是%s %s %d %d\n",s.base[i].location,s.base[i].name,s.base[i].number,s.base[i].score,s.base[i].num); 
}
int main()
{
     Message s;
	 int a;
	 Creat(s);
		while (1)
		{
			printf("==============================================\n");
		   printf("1.录入学生信息:\n2.直接插入排序:\n3.冒泡排序:\n4.快速排序:\n5.简单选择排序:\n6.堆排序:\n7.2-路归并排序:\n8.输出学生信息:\n9.退出\n");
		   scanf("%d",&a);
		   switch(a)
		   {
		   case 1:Print(s.base,s.num);break;
		   case 2:Sort1(s);break;
		   case 3:Sort2(s);break;
		   case 4:Sort3(s);break;
		   case 5:Sort4(s);break;
		   case 6:Sort5(s);break;
		   case 7:Sort6(s);break;
		   case 8:Put(s);break;
		   case 9:return 0;
		   }
		}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值