链表实现简单学生信息管理

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#define len sizeof(struct stu)
typedef long long ll;
struct stu                   //建立学生信息的结构体,包含学号,姓名 ,成绩三个子项 
{
	ll num;
	char a[50];
	double score;
	struct stu *next;
} ;
struct stu *creat()                  //建立一个链表 
{
	struct stu *head;
	struct stu *p;
	struct stu *tail;
	head=tail=NULL;                //表头表尾指针初始化为空 
	printf("请按照学号从小到达的顺序输入学生的信息,中间用空格隔开,学号输入0表示输入结束:\n学号:\t姓名:\t分数:\n");
	ll x;
	scanf("%lld",&x);             //输入学号 
	getchar();
	while(x!=0)
	{
		p=(struct stu*)malloc(len);        //以学号输入0为结束,当学号不为0时,建立一个新的节点 
		p->num=x;                          
		if(head==NULL)                    //如果头指针为空,则把头指针指向第一个节点 
		   head=p;
		if(tail!=NULL)                   
		   tail->next=p;
		tail=p;                                //尾指针也指向新建立的节点 
		scanf("%s%lf%lld",p->a,&p->score,&x);  //输入姓名成绩和下一个学号 
	}
	if(tail!=NULL)                       //将尾节点的后继设置为空 
	tail->next=NULL; 
	return head;
}
void list(struct stu *p)                //显示链表里的信息 
{
	struct stu *head;
	head=p;
	if(head==NULL)                 
	printf("您并没有输入任何信息\n");    //如果头为空则证明没有输入任何和信息 
	else
	{
	printf("学号:\t姓名:\t分数:\n");
	while(head!=NULL)
	{
		printf("%lld\t%s\t%5.1lf\n",head->num,head->a,head->score);  //输出节点里的学生信息 
		head=head->next;      //读取下一个节点 
	} 
    }
}
void query(char c[],struct stu *head)   //按姓名查找学生信息 
{
	struct stu *p;
	p=head;
	while(strcmp(p->a,c)!=0)
	{
		p=p->next;
	}
	printf("学号:\t姓名:\t分数:\n");
	printf("%lld\t%s\t%5.1lf\n",p->num,p->a,p->score);
}
struct stu *delet(char c[],struct stu *head)
{
	struct stu *p,*temp;                //设置两个结构体指针,分别指向要删除学生的信息节点和它的前驱节点 
	p=temp=head;
	if(p==NULL)
	{
		printf("并没有任何学生信息\n"); //如果链表为空则按情况输出 
	}
	else
	{
    while(strcmp(p->a,c)!=0 && p->next!=NULL)  //当没有查询到指定学生并且没有遍历链表时一直向后查询 
    {
    	temp=p;
    	p=p->next;
	}
    if(strcmp(p->a,c)==0)
    {
    	if(p==head)                     //如果要删除的学生信息位于链表的头节点时直接删除并将头节点设置为下一个节点 
    	{
    		printf("姓名为:%s的学生信息已删除,按2查看\n",c);
			head=head->next;    
            free(p);
		}
		else                          //其他情况下将删除掉节点的前驱节点的尾指针指向删除节点的下一个节点 
	    {
	        printf("姓名为:%s的学生信息已删除,按2查看\n",c);
	        temp->next=p->next;
	        free(p);
		}
	}
	else
	{
		printf("没有找到这个名字的学生\n");   //如果没有找到则按情况输出 
	}
}
return head;
}
struct stu *add(ll k,char name[],int scor,struct stu *head) 
{
	struct stu *p,*temp,*q; p=temp=head;
	if(p->num > k)                                //按学号添加学生信息,当头节点的学号大于当前学号时插入到表头 
	{
		p=(struct stu *)malloc(len);
		p->next=head;
		head=p;
        p->num=k; strcpy(p->a,name); p->score=scor;
        printf("学生信息已添加,按2查看\n"); 
	}
	else
	{
	while(p->next!=NULL)
	{
		temp=p;
		p=p->next;
		if(temp->num < k && p->num>k)               //当要插入的学号位于某两个学号之间时插入到这两个节点之间 
		{
			q=(struct stu *)malloc(len);
			temp->next=q;
			q->next=p;
			q->num=k; strcpy(q->a,name); q->score=scor;
			printf("学生信息已添加,按2查看\n");
		}
	}
	if(p->num < k)                                  //当要添加的学生学号大于表尾学号时插入到表尾 
	{
		q=(struct stu *)malloc(len);
		p->next=q;  q->next=NULL;
		q->num=k; strcpy(q->a,name); q->score=scor;
		printf("学生信息已添加,按2查看\n");
	}
}
	return head;
}
struct stu *pos1(ll k, char name[], int scor, int pos, struct stu *head)
{
	struct stu *p,*temp; p=temp=head;             //按位置添加学生信息 
	int num=0;
	while(p!=NULL)
	{
		p=p->next;
		num++;
	}
	p=temp=head;
	if(pos==1)                               //当位置是1时添加到表头 
	{
		p=(struct stu *)malloc(len);
		p->next=head; head=p;
		strcpy(p->a,name);
		p->num=k; p->score=scor;
		printf("学生信息已添加,按2查看:") ;
	}
	else if(pos>1 && pos<=num)                //当要添加的学生位置在表中时添加到表中 
	{
		int l=0;
		while(p!=NULL)
		{
			temp=p;
			p=p->next; 
			l++;
			if(l=pos)
			{
			    struct stu *q=(struct stu *)malloc(len);
			    q->next=p;  temp->next=q;
			    strcpy(q->a,name);
		        q->num=k; q->score=scor;
		        printf("学生信息已添加,按2查看:") ;
		        break;
			}
		}
	}
	else if(pos==num+1)                           //当位置在最后时添加到表尾 
	{
		struct stu *q=(struct stu *)malloc(len);
		while(p->next!=NULL)
		{
			p=p->next;
		}
		p->next=q; q->next=NULL;
		strcpy(q->a,name);
		q->num=k; q->score=scor;
		printf("学生信息已添加,按2查看:") ;
	}
	else
	printf("对不起,您输入的位置无效\n");                 //其他情况下输出位置无效的信息 
	return head; 
}
struct stu *pos2(int n,struct stu *head)                   //按位置查询学生信息,遍历链表,当位置符合时输出学生信息 
{
	struct stu *p,*temp;
	p=head; int m=0,ans=0;
	if(p==NULL)
	printf("没有任何学生信息\n");
	else
	{
	while(p!=NULL)
	{
		temp=p;
		p=p->next;
		m++;
		if(m==n)
		{
	        printf("学号:\t姓名:\t分数:\n");
         	printf("%lld\t%s\t%5.1lf\n",temp->num,temp->a,temp->score);
         	ans=1;
         	break;
		}
	}
	if(ans==0)
	printf("对不起,您输入的位置无效\n");
    }
    return head;	
} 
void query2(struct stu *head)                   //查询学生数量 
{
	struct stu *p;
	p=head;
	int n=0;
	while(p!=NULL)
	{
		n++;
		p=p->next;
	}
	printf("学生数量为:%d个\n",n);
} 
int main()
{
	printf("\t\t\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\n");
	printf("\n\n\t\t\t\t学生成绩管理系统\n\n\n");
	printf("\t\t\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\1\2\n");
	printf("\n\n\n\t\t\t\t1:输入学生信息\n") ;
	printf("\n\t\t\t\t2:显示学生信息\n");
	printf("\n\t\t\t\t3:根据姓名查询学生信息\n");
	printf("\n\t\t\t\t4:根据姓名删除学生信息\n");
	printf("\n\t\t\t\t5:根据学号添加学生信息\n");
	printf("\n\t\t\t\t6:输入位置添加学生信息\n");
	printf("\n\t\t\t\t7:输入位置查询学生信息\n");
    printf("\n\t\t\t\t8:查询学生数量\n");
	printf("\n\t\t\t\t0:退出系统\n");
	printf("\n\t\t\t\t请按0-4选择菜单项:\n");
	int n,k,scor,pos,m=0; char b[50],name[50];
	struct stu *head; 
	while(scanf("%d",&n))
{	
    if(n==0)
       break;
    if(m==0&&n!=1)
    {
    	printf("请先输入成绩后才能进行操作\n");
    	continue;
	}
	m=1;
	switch(n)
	{
		case 1: head=creat(); break; 
		case 2: list(head); break;
		case 3: printf("请输入要查询的学生姓名:"); 
		            scanf("%s",b); query(b,head); break;
	    case 4: printf("请输入要删除的学生姓名:");
                    scanf("%s",b); head=delet(b,head);  break;
        case 5: printf("请输入要添加的学生的信息:学号:\t姓名:\t分数:");
                    scanf("%lld",&k); getchar(); scanf("%s%d",name,&scor); head=add(k,name,scor,head);  break; 
        case 6: printf("请输入要添加的学生的信息:学号:\t姓名:\t分数:\t位置:");
                    scanf("%lld",&k); getchar(); scanf("%s%d%d",name,&scor,&pos); head=pos1(k,name,scor,pos,head); break; 
        case 7: printf("请输入要查询的学生的位置:");
                    scanf("%d",&pos);  head=pos2(pos,head); break;
        case 8: query2(head); 
		           
	}
}
	return 0;	
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值