<单链表>实现简单的学生成绩管理系统

5 篇文章 0 订阅
5 篇文章 0 订阅
本文介绍了如何使用C语言创建一个学生信息管理系统,该系统基于链表数据结构,支持学生信息的批量录入、删除、冒泡排序以及数据的导出和导入功能。主要操作包括头插法和尾插法的插入、按学号删除、遍历输出、冒泡排序和文件I/O操作。
摘要由CSDN通过智能技术生成

该链表是在我上一篇链表文章的基础上稍加改动的

实现批量录入、批量删除、冒泡排序、批量导入、导出到本地等功能

/***********阿布君*****************/
//该链表是在我上一篇文章的基础上稍加改动的 
/*总体思路就是,相较于单链表原型,其实该管理系统只是使链表的每个结点的数据域存储一个结构体使
其存储一个学生的全部信息,然后指针后移 */

#include<stdio.h> 
#include<stdlib.h>		//malloc需要用到该头文件

/********/
//定义一个学生信息结构体
typedef struct student  
{
	char name[10];
	int age;
	char sex;
	long long int xuehao;
	int grades;
 } ST;

//1.首先创建一个链表结构------->数据域+指针 
typedef struct NODE
{
	int size; //------->用表头存储链表中学生个数 
	ST s;  //---------->直接在数据域改为结构体
	struct NODE* next; 
 }LNODE;               //typedef将struct NODE改名为LNODE(结构体类型标识符) 

//2.创建一个表头
LNODE* creatlist()
{
	LNODE* head=(LNODE*)malloc(sizeof(LNODE));              //头节点一般不给数据(也可以拓展让其存储链表长度) 
	head->next=NULL;
	head->size=0;    //初始化时置零 
	return head;
 } ; 
 
//3.创建一个结点--------->为4.为插入结点作定义 
LNODE* creatNODE(ST s)//(int data) 
{
	LNODE* PNODE=(LNODE*)malloc(sizeof(LNODE));
	//PNODE->data=data;
		PNODE->s=s;
	PNODE->next=NULL;
	return PNODE;
};

//4.插入一个结点------------>头插法(head->......、4、3、2、1) 
void insert(LNODE* head,ST s)//int data)
{
	LNODE* newNODE=creatNODE(s);//(data);
	newNODE->next=head->next;             //总是从head->next插入 
	head->next=newNODE; 
 } 

/**///尾插法------(head->1、2、3、4、......)
void wcinsert(LNODE* head,ST s)//int data)
{
	LNODE* newNODE=creatNODE(s);//(data);
	LNODE* pmove=head;
	while(pmove->next!=NULL)               //总是先遍历完当前链表,使指针指向表尾 
	{
		pmove=pmove->next;
	}
	pmove->next=newNODE;        
	head->size++;           //存入表尾 
}

//5.删除一个结点
void del(LNODE* head,long long k)//int data)
{
	if(head->next==NULL)                     //先判断链表是否为空很有必要 
	{
		printf("该链表中无任何信息!\n");
		return; 
	}
	LNODE* P=(LNODE*)malloc(sizeof(LNODE));    //定义一个当前结点指针和上一个结点的指针记录 
	LNODE* PF=(LNODE*)malloc(sizeof(LNODE));
	P=head->next;
	PF=head;
	while(P)                             //判断是否循环完链表 
	{
		//if(P->data==data)     
		if(P->s.xuehao==k)          //循环直到找到该数据 
		{
			PF->next=P->next;
			free(P);               //------>一定要free释放内存空间,防止地址溢出 
			head->size--;
			printf("删除成功!");
			return ;
		}
		PF=P;
		P=P->next;
	}
	printf("未找到该学生!");
 } 
 
//6.遍历输出
void print(LNODE* head)
 {
 	if(head->next==NULL)
	{
		printf("该链表中无任何信息!\n");
		return; 
	}
 	LNODE* Pmove=(LNODE*)malloc(sizeof(LNODE));         //用一个指针来循环整个链表 
 	Pmove=head->next;
 	printf("学生信息数据如下:\n"); 
 	printf("	姓名\t	年龄\t	性别\t	学号\t	成绩\n");
 	while(Pmove)
 	{
 		printf("	%s\t	%d\t	%c\t	%lld\t	%d\t\n",Pmove->s.name,Pmove->s.age,Pmove->s.sex,Pmove->s.xuehao,Pmove->s.grades);
 		Pmove=Pmove->next;
	 }
	 printf("\n");
  } 
  
//**7.连续插入结点
int progress(LNODE* head)
{
	ST s; 
	int i,n=0;
	printf("请输入要插入几位同学的信息:");
	scanf("%d",&n);
	printf("请依次输入学生的:姓名 年龄 性别(M%cm或者W%cw) 学号 成绩\n",92,92);    //92是'\'的ASCII码 
	for(i=0;i<n;i++)
	{
		printf("请输入第%d个数的数据:",i+1);
		scanf("%s %d %c %lld %d",s.name,&s.age,&s.sex,&s.xuehao,&s.grades);  //注意:第一个s.name不用加&
		//insert(head,k);             //头插法 
		wcinsert(head,s);             //尾插法 
	}
	printf("添加完成!"); 
	return 0; 
}

//**8.连续删除结点
void dell(LNODE* head) 
{
	if(head->next==NULL)
	{
		printf("该链表中无任何信息!\n");
		return; 
	}
	int i,n=0;
	long long int k=0;
	printf("请输入要删除几位同学信息:");
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		printf("请输入要删除的第%d个同学的学号:",i+1);
		scanf("%d",&k);
		del(head,k); 
	}
}

//**9.成绩排序(冒泡)   这里我定义了一条新的链表来存储排序后的数据 
 void comp(LNODE* head)
 {  
 	if(head->next==NULL)
	{
		printf("该链表中无任何信息!\n");
		return; 
	}

 	LNODE* head2 = (LNODE*)malloc(sizeof(LNODE));
head2->next = NULL;
head2->size = head->size;

LNODE* h = head->next;
LNODE* h2 = head2;  // 将h2指针先指向head2

while(h)
{
    LNODE* newNODE = creatNODE(h->s);  // 创建一个新的结点
    h2->next = newNODE;                // 将该结点插入到head2链表的尾部
    h = h->next;
    h2 = h2->next;
}

LNODE* pf = head2;
LNODE* p = pf->next;
int i=0,j=0;
for(i = 0; i < head2->size; i++)
{
    pf = head2;
    p = pf->next;
    for(j = 0; j < head2->size - i - 1; j++)
    {
        if(p->s.grades < p->next->s.grades) 
        {
            LNODE* temp = p->next;
            p->next = temp->next;
            temp->next = p;
            pf->next = temp;
            p = temp;
        }
        pf = p;
        p = p->next;
    }
}
print(head2);
}
  
//**10.导出成txt文件到桌面
void dataout(LNODE* head)
{
	if(head->next==NULL)
	{
		printf("该链表中无任何信息!\n");
		return; 
	}
	FILE* fp;
	fp=fopen("lbs.txt","w");       //文件没有就创建,存在就覆盖 
	if (fp == NULL)
    {
        printf("打开文件失败!\n");
        return;
    }
	int i=0;
	LNODE* Pmove=(LNODE*)malloc(sizeof(LNODE));         //用一个指针来循环整个链表 
 	Pmove=head->next;
	//fprintf(fp,"	姓名\t	年龄\t	性别\t	学号\t	成绩\n");
 	while(Pmove)
 	{
 		fprintf(fp,"	%s\t	%d\t	%c\t	%lld\t	%d\t\n",Pmove->s.name,Pmove->s.age,Pmove->s.sex,Pmove->s.xuehao,Pmove->s.grades);
 		Pmove=Pmove->next;
 		i++;
	 }
	printf("导出成功!\n");
	head->size=i;
	fclose(fp);
 } 
 
void fin(LNODE* head)
{
 	
	FILE *fp;
	fp=fopen("lbs.txt","r");
	if (fp == NULL)
    {
        printf("打开文件失败!\n");
        return;
    }
	char line[100];
	while(fgets(line, sizeof(line), fp))
	 {
		ST s;
		sscanf(line, "%s %d %c %lld %d", s.name, &s.age, &s.sex, &s.xuehao, &s.grades);
		wcinsert(head, s);
	}
	printf("导入成功!\n");
	fclose(fp);
 } 
void menu()
{
	printf("/**********************菜单***************************/\n");
	printf("              1.显示菜单\n");
	printf("              2.输入学生信息\n");
	printf("              3.学号删除学生信息\n");
	printf("              4.显示全部学生的信息\n");
	printf("              5.按成绩高低排名\n");
	printf("              6.文件形式导出到桌面\n");
	printf("              7.从本地文件中导入\n");
	printf("              8.退出!\n"); 
}

//***************************主程序*********************************// 
void main()
{
	int i=0,j=1;
	LNODE* head=creatlist();
	menu(); 
	while(j)
	{
		printf("请输入操作:");
		scanf("%d",&i);
		switch(i)
		{
			case 1:
					menu();break;
			case 2:
					progress(head);break;
			case 3:
					dell(head);break;
			case 4:
					print(head); break;
			case 5:
					comp(head);break; 
			case 6:	
					dataout(head);break;
			case 7:
					fin(head);break;
			case 8: 
					j=0;		
		}
		
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值