数据结构——学生成绩管理系统的链表实现

博主在考研复习数据结构时,根据严蔚敏老师的《数据结构》,重构了代码。最开始的代码(代码2)参考自《C语言教程》是一个类似封装好的链表实现。这份新的代码大部分参考自严蔚敏老师的《数据结构》,加入了自己的理解。

系统提供增、删、查、改、看 五项操作
初成代码,如果有BUG 还望指出,共同学习。

代码一:
带头结点的单链表实现。

#include<bits/stdc++.h>
using namespace std;
#define line cout << "-----------------" << endl
#define Status bool
#define ElemType LNode

typedef struct LNode{
    char id[15];
    char name[20];
    double score;
    struct LNode *next;
}LNode, *LinkList;

LinkList L;
int sum;

void CreatList(LinkList &L, int n){//后插法创建单链表
    L = new LNode;
    L->next = NULL;
    LNode *r = L;

    for(int i = 0; i < n; i++){
        LNode *p = new LNode;
        scanf("%s %s %lf", p->id, p->name, &p->score);
        p->next = NULL;
        r->next = p;
        r = p;
    }
}
void PrintList(LinkList &L){
    printf("学号:\t姓名:\t成绩:\n");
    LNode *p = L->next;
    while(p != NULL){
        printf("%s\t%s\t%lf\n", p->id, p->name, p->score);
        p = p->next;
    }
}
void ListFind(LinkList, char s[]){
    LNode *p = L->next;
    int j = 0;
    while(p != NULL){
        if(strcmp(p->id, s)== 0){
            printf("学号:\t姓名:\t成绩:\n");
            printf("%s\t%s\t%lf\n", p->id, p->name, p->score);
            printf("查找成功\n");
            return;
        }
        p = p->next;
        j++;
    }
    printf("查找失败,请核查信息是否正确\n");
    return;
}
/*
Status GetElem(LinkList L, int i, ElemType &e){
    LNode *p = L->next;
    int j = 1;
    while(p && j < i){
        p = p->next;
        j++;
    }
    if(!p || j > i) return false;
    e = p - > date;
    return true;
}
LNode *LocateElem(LinkList L, ElemType e){
    LNOde *p = L->next;
    while(p && p->data != e){
        p = p->next;
    }
    return p;
}
*/

Status ListInsert(LinkList &L, int i, ElemType *e){
    sum ++;
    LNode *p = L;
    int j = 0;
    while(p && (j < i-1)){
        p = p->next;
        j++;
    }
    if(!p || j > i-1) {
        printf("插入失败,请核查信息是否正确\n");
        return false;
    }
    LNode *s = new LNode;
    s = e;
    s->next = p->next;
    p->next = s;
    printf("插入成功\n\n");
    return true;
}

Status ListDelete(LinkList &L, int i){
    sum--;
    LNode *p = L;
    int j = 0;
    while((p->next) && (j<i-1)){
        p = p->next;
        j++;
    }
    if(!(p->next) || (j > i-1) ){
        printf("删除失败,请核查信息是否正确\n");
        return false;
    }
    LNode *q = p->next;
    p->next = q->next;
    delete q;
    return true;
}
Status ListChange(LinkList &L, int i, ElemType *e){
    LNode *p = L;
    int j = 0;
    while((p->next) && (j<i-1)){
        p = p->next;
        j++;
    }
    if(!(p->next) || (j > i-1) ){
        printf("查找失败,请核查信息是否正确\n");
        return false;
    }
    p = p->next;
    strcpy(p->id, e->id);
    strcpy(p->name, e->name);
    p->score = e->score;
    printf("修改成功\n");
    return true;
}
int main(){
    printf("欢迎使用学生成绩管理系统:\n");
    printf("本系统由带头结点的单链表实现\n");
    printf("首次进入系统请先输入数据\n\n");
    printf("请输入学生总人数:\n");
    cin >> sum;
    line;
	printf("请依次输入学生的学号、姓名和成绩\n");
    CreatList(L, sum);
    printf("初始化成功!\n");
    PrintList(L);
    printf("系统提供增、删、查、改、看 五项操作\n");
    char op[2];
    printf("请选择您所需要的操作:\n");
    printf("输入1:增加学生信息\n");
    printf("输入2:删除学生信息\n");
    printf("输入3:查找学生信息\n");
    printf("输入4:修改学生信息\n");
    printf("输入5:查看系统数据\n");
    printf("输入#:退出系统\n");
    scanf("%s", op);
    while(true){
        if(op[0] == '1'){
            LNode *x = new LNode;
            int pos = -1;
            printf("请依次输入插入学生的学号、姓名和成绩\n");
            scanf("%s %s %lf", x->id, x->name, &x->score);
            x->next = NULL;
            printf("请输入插入的位置\n");
            scanf("%d", &pos);
            ListInsert(L, pos, x);
        }
        else if(op[0] =='2'){
            int pos = -1;
            printf("请输入要删除的学生的位置\n");
            scanf("%d", &pos);
            ListDelete(L, pos);
        }
        else if(op[0] =='3'){
            printf("请输入要查找的学生的学号:\n");
            char s[20];
            scanf("%s", s);
            ListFind(L, s);
        }
        else if(op[0] =='4'){
            LNode *x = new LNode;
            int pos = -1;
            printf("请依次输入插入修改后学生的学号、姓名和成绩\n");
            scanf("%s %s %lf", x->id, x->name, &x->score);
            x->next = NULL;
            printf("请输入要修改的学生的位置\n");
            scanf("%d", &pos);
            ListChange(L, pos, x);
        }
        else if(op[0] =='5') PrintList(L);
        else if(op[0] =='#') break;
        else printf("错误输入\n");
        printf("\n\n请选择您所需要的操作:\n");
        printf("输入1:增加学生信息\n");
        printf("输入2:删除学生信息\n");
        printf("输入3:查找学生信息\n");
        printf("输入4:修改学生信息\n");
        printf("输入5:查看系统数据\n");
        printf("输入#:退出系统\n");
        scanf("%s", op);
    }
    printf("感谢您使用学生成绩管理系统。\n");
    printf("\t\t\t作者 : 辞树");
    return 0;
}

代码二:

#include<bits/stdc++.h>
#define LEN sizeof(struct stu)
using namespace std;
struct stu
{
	int num;												//学生学号
	char name[20]; 											//学生姓名
	float score;											//学生成绩
	struct stu *next;										//指针后移
};
struct stu *creat()											//创建链表
{
	struct stu *head;										//头指针
	struct stu *p;											//临时指针
	struct stu *tail;										//尾指针
	int x;
	tail = head = NULL;										//将头尾指针初始化
	scanf("%d",&x);											//x为学生的学号
	while(x!=0)
	{
		p = (struct stu *)malloc(LEN);
		p->num = x;
		if(head == NULL)
			head = p;
		scanf("%s %f",p->name,&p->score);
		if(tail != NULL)
			tail->next = p;
		tail = p;
		scanf("%d",&x);
	}
	if(tail != NULL)
		tail -> next = NULL;
	return (head);
}
struct stu *Insert(struct stu *head,struct stu *stud)		//插入新的结点   *head 指向链表的首地址,stud为要插入的学生的结构体的地址
{
	struct stu *p0;											//p0指向要插入的新节点
	struct stu *p1;											//p1指向链表中第一个学号大于新节点的学号的节点
	struct stu *p2;											//p2指向p1的前驱节点,即p2的next域指向p1
	p0 = stud;												//新节点的地址
	p1 = head;												//链表的首地址给p1
	if(head == NULL)										//如果头指针不存在
	{
		head = p0;											//就把新插入的指针地址设置为首地址,新插入的指针的尾指针指向空
		p0->next=NULL;
	}
	else
	{
		while((p1!=NULL)&&(p0->num >= p1->num))				//查找。两个条件的顺序不能对调,否则p1的值为NULL时,还要再访问p1->num,将出现访问零地址的错误
		{													//找到第一个成立的
			p2 = p1;
			p1 = p1->next;
		}
		if(p1!=NULL)										//如果不是刚好插入链表的尾部
		{
			if(head == p1)									//如果p0->num == p1->num 的情况成立
				head = p0;
			else 											// 如果p0->num == p1->num 的情况不成立
				p2->next=p0;
			p0->next=p1;
		}
		else												//如果要插入的刚好是在链表的尾部
		{
			p2->next=p0;
			p0->next=NULL;
		}
	}
	return head;											//返回插入学生的地址
}
struct stu *del(struct stu *head ,int num)
{
    struct stu *p1;
    struct stu *p2;
    if(head == NULL)
        printf("链表为空\n");
    else
    {
        p1 = head;
        while(p1!=NULL&&p1->num!=num)
        {
            p2=p1;
            p1=p1->next;
        }
        if(p1->num==num)
        {
            if(p1==head)
                head=p1->next;
            else
                p2->next=p1->next;
            printf("删除的学生的学号:%d\n",num);
            free(p1);
        }
        else
        {
            printf("学号为%d的学生没有被找到!\n");
        }
    }
    return (head);
}
void List(struct stu *head)
{
	struct stu *p;
	p = head;
	if(head !=NULL)
	{
		printf("学生的成绩列表为:\n");
		printf("学号\t姓名\t成绩\n");
		do
		{
			printf("%d\t%s\t%5.1f\n",p->num,p->name,p->score);
			p = p->next;									//p指针后移
		}while(p!=NULL);
	}
	else
	{
		printf("链表为空\n\n");
	}
	cout<<endl<<endl;
}
int main()
{
	printf("\t\t······欢迎来到学生成绩管理系统······\n\n");
	printf("首次进入系统请先输入数据\n\n");
	printf("请依次输入学生的学号、姓名和成绩(当输入的学号为0时,输入数据结束)\n");
	struct stu *head;
	head = creat();
	List(head);
	int temp;
	printf("请选择需要进行的操作:\n");
	printf("不需要更改请输入“0”\n");
	printf("对学生的信息进行修改请输入“1”\n");
	printf("查找学生的信息请输入“2”\n");
	scanf("%d",&temp);
	while(temp)
	{
		if(temp==1)
		{
			printf("请选择需要修改的内容:\n");
			printf("增加学生数据请输入“1”\n");
			printf("删除学生数据请输入“2”\n");
			printf("更改学生数据请输入“3”\n");
			int te;
			scanf("%d",&te);
			if(te==1)											//增加学生数据
			{
				struct stu *newstu;
				printf("请输入学生学号、姓名和成绩(输入学号为0时,输入结束)\n");
				int num;
				//head = NULL;
				scanf("%d",&num);
				while(num!=0)
	            {
	                newstu=(struct stu *)malloc(sizeof(struct stu));
	                newstu->num=num;
	                scanf("%s %f",newstu->name,&newstu->score);
	                head = Insert(head,newstu);
	                scanf("%d",&num);
	            }
	            List(head);
			}
			else if(te == 2)									//删除学生数据
			{
	            struct stu *newstu;
	            int num;
	            printf("请输入需要删除的学生的学号:\n");
	            scanf("%d",&num);
	            head = del(head,num);
	            List (head);
			}
			else if(te == 3)									//更改学生数据
			{
				printf("请输入需要更改的学生的学号和成绩:\n");
				int tt,ts;
				scanf("%d%d",&tt,&ts);
				struct stu *p;
				p=head;
				while(p->num!=tt)
					p=p->next;
				p->score=ts;
				printf("修改成功\n");
				printf("该生的个人信息如下:\n");
				printf("学号\t姓名\t成绩\n");
				printf("%d\t%s\t%f\n\n",p->num,p->name,p->score);
			}
		}
		else if(temp == 2)										//查找学生 
		{
			struct stu *p;
			p = head;
		//	int flag=0;
			printf("请输入需要查找的学生的学号:\n");
			int se;
			scanf("%d",&se);
			printf("该生的个人信息如下:\n");
			printf("学号\t姓名\t成绩\n");
			while(p&&p->num!=se)
			{
				p=p->next;
			}
			if(!p->num)
				printf("查无此人!\n");
			else
				printf("%d\t%s\t%f\n\n",p->num,p->name,p->score);
		}
		printf("请选择需要进行的操作:\n\n");
		printf("不需要更改请输入“0”\n");
		printf("对学生的信息进行修改请输入“1”\n");
		printf("查找学生的信息请输入“2”\n");
		scanf("%d",&temp); 
	}
	List(head); 
	printf("感谢您使用学生成绩管理系统,欢迎再次使用\n");
	printf("\t\t\t\t\t\t作者:辞树\n\n");
	return 0;
 }

  • 5
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值