一个结构体数组中插入一组数据,原结构体数组中的数据按平均成绩由大到小排序,现在插入一个之后还是这样排序输出

//文件中存放了20个由小到大的排列的整数,现在从键盘上输入一个数,要求把该数插入此文件中,保持文件特性不变。
//基本思想是:先从文件中读取那20个数放入字符数组中,然后再对字符数组进行操作
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define M 5
struct ST{
  char name[10];
  int num;
  int age;
  char addr[5];
  int s[3];
  float ave;

}stu[M],temp,m;

void save()
{
//借助一个中间变量进行实现
 
  int i,j,k,t;
  float sum=0;
 
  FILE *fp;

  if((fp=fopen("t.dat","wb"))==NULL)
  {
    printf("error");
	exit(0);
  }

//实现按学生的平均分的高低进行排序,这里用选择排序来实现吧
for(i=0;i<3-1;i++)
{
   k=i;
   for(j=i+1;j<3;j++)
    if(stu[j].ave>stu[k].ave)
	   k=j;
	//注意这块进行交换的是结构体数组,不是单个比较的数据项
    temp=stu[i];
	stu[i]=stu[k];
	stu[k]=temp;
}

printf("请输入一个学生的信息包括姓名学号年龄和地址\n");
scanf("%s %d %d %s",m.name,&m.num,&m.age,m.addr);
printf("输入这三个学生的成绩:\n");
for(i=0;i<3;i++)
{
   printf("输入第%d一门课的成绩;\n",i+1);
   scanf("%d",&m.s[i]);
   sum+=m.s[i];
}
m.ave=sum/3;  //求新插入的这个学生的平均分


printf("这个学生的均分是%d\n",m.ave);
//遍历找位置,
for(i=0;i<3;i++)
{
   if(stu[i].ave>m.ave)
	  {
	   t=i;
	   }
}

for(i=0;i<=t;i++)
{
  if((fwrite(&stu[i],sizeof(struct ST),1,fp))!=1)
		printf("file write error");
}

fwrite(&m,sizeof(struct ST),1,fp);

for(i=t+1;i<M;i++)
{
  if((fwrite(&stu[i],sizeof(struct ST),1,fp))!=1)
		printf("file write error");
}
//算法思想:先写入前面的有序的部分,然后再写入待插入的这个结构体,最后再插入后面一截即可
//注意:待插入的这个结构体


rewind(fp);
if((fp=fopen("t.dat","rb"))==NULL)
{
  printf("error");
  exit(0);
}
printf("输出排序好的顺序:\n");
for(i=0;i<4;i++)
{
//	fseek(fp,i*sizeof(struct s),0);//移动文件标志
   fread(&stu[i],sizeof(struct ST),1,fp);
   printf("%-10s %4d %4d %-15s %4f\n",stu[i].name,stu[i].num,stu[i].age,stu[i].addr,stu[i].ave);
}
  fclose(fp);
}


//主函数

int main()
{
  //FILE *fp;
int i,k=0,j;
float sum=0;
printf("输入学生的数据:\n");
for(i=0;i<3;i++)
{  printf("请输入第%d学生的学号和姓名(分别用空格隔开)\n",i+1);
  scanf("%s%d%d%s",stu[i].name,&stu[i].num,&stu[i].age,stu[i].addr);
   sum=0;
     for(j=0;j<3;j++)
	 {
	  printf("请输入第%d学生的第%d门课程成绩(分别用空格隔开)\n",i+1,j+1);
	  scanf("%d",&stu[i].s[j]);
	  	  sum+=stu[i].s[j];
	 }
//计算的是每个学生的平均成绩
	 //要求读写到磁盘中,可以在结构体中定义一个ave属性,然后用fwrite一块写入磁盘。
	stu[i].ave=sum/3;
}

  save();
 return 0;
 //验证t.dat中是否有这个文件

}

注意方法:先比较原结构体中的排序好的平均成绩和现在需要插入的平均成绩的大小关系,找出需要插入的平均成绩所在的位置

然后记录这个点,,记住:t。最后先把t位置之前的都写入文件中,再写入t位置上的数据(即要插入的数据),最后把要插入数据之后的所有内容全部写入文件,即实现了插入后排序

如有不足,请指正!!

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我来回答你的问题。 首先,这是一个定义结构体数组的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LEN 20 struct Student { int id; char name[20]; float score; }; struct Student students[MAX_LEN]; ``` 接下来,我会分别介绍插入排序、选择排序、冒泡排序、快速排序和折半查找的实现方法。 1. 插入排序 插入排序的思路是,将未排序的元素插入到已排序的子序列。具体实现方法可以参考下面的代码: ```c void insertion_sort(struct Student array[], int len) { int i, j; struct Student temp; for (i = 1; i < len; i++) { temp = array[i]; j = i - 1; while (j >= 0 && array[j].id > temp.id) { array[j + 1] = array[j]; j--; } array[j + 1] = temp; } } ``` 2. 选择排序 选择排序的思路是,每次选出未排序的最小元素,将其放到已排序的末尾。具体实现方法可以参考下面的代码: ```c void selection_sort(struct Student array[], int len) { int i, j, min_index; struct Student temp; for (i = 0; i < len - 1; i++) { min_index = i; for (j = i + 1; j < len; j++) { if (array[j].id < array[min_index].id) { min_index = j; } } if (min_index != i) { temp = array[i]; array[i] = array[min_index]; array[min_index] = temp; } } } ``` 3. 冒泡排序 冒泡排序的思路是,每次比较相邻的两个元素,如果它们的顺序不对就交换它们。具体实现方法可以参考下面的代码: ```c void bubble_sort(struct Student array[], int len) { int i, j; struct Student temp; for (i = 0; i < len - 1; i++) { for (j = 0; j < len - i - 1; j++) { if (array[j].id > array[j + 1].id) { temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; } } } } ``` 4. 快速排序 快速排序的思路是,选择一个基准元素,将小于它的元素放到左边,大于它的元素放到右边,再对左右两个子序列分别进行快速排序。具体实现方法可以参考下面的代码: ```c void quick_sort(struct Student array[], int left, int right) { int i, j; struct Student pivot, temp; if (left < right) { pivot = array[left]; i = left; j = right; while (i < j) { while (i < j && array[j].id >= pivot.id) { j--; } if (i < j) { array[i] = array[j]; i++; } while (i < j && array[i].id < pivot.id) { i++; } if (i < j) { array[j] = array[i]; j--; } } array[i] = pivot; quick_sort(array, left, i - 1); quick_sort(array, i + 1, right); } } ``` 5. 折半查找 折半查找的思路是,将已排序的序列分成两半,如果要查找的元素比间元素小就在左半部分继续查找,否则在右半部分继续查找。具体实现方法可以参考下面的代码: ```c int binary_search(struct Student array[], int len, int key) { int left = 0; int right = len - 1; int mid; while (left <= right) { mid = (left + right) / 2; if (array[mid].id == key) { return mid; } else if (array[mid].id < key) { left = mid + 1; } else { right = mid - 1; } } return -1; } ``` 最后,你可以将这些函数组合起来,实现一个完整的程序。需要注意的是,在使用折半查找之前,需要先对数组进行排序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sustyle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值