基于C语言单链表的成绩管理程序

来源:互联网 发布:2010年nba科比数据 编辑:程序博客网 时间:2024/04/26 22:53

单向链表实现增删改查

1.数据结构

typedef struct item{item *prev = NULL;item *next = NULL;char name[20];int math;int cna;int eng;int avg;bool flag = false;//有内容标志,可以忽略掉第一个数据得问题}date;

*prev------------->指向上一个数据存储空间的指针
*next------------->是指向下一个数据存储空间的指针

name------------>姓名char数组
cna--------------->语文成绩
eng--------------->英语成绩
math------------->数学成绩
avg--------------->平均分

flag-------------->是否具有数据标志,可以避免释放表头出现的内存泄漏问题

2.链表增加项目

void additem()//增{date *head;date *ptr;ptr = &first;while (true){if (ptr->flag == false)//该内存区域下没有数据{printf("name:\n");fflush(stdin);//清除缓存空间 否则gets_s会因为检测缓存空间的空字符而跳过gets_s(ptr->name);printf("Math:\n");scanf_s("%d", &ptr->math);printf("Chinese:\n");scanf_s("%d", &ptr->cna);printf("English:\n");scanf_s("%d", &ptr->eng);ptr->avg = (ptr->cna + ptr->eng + ptr->math) / 3;ptr->flag = true;printf("write succed!\n\n\n");break;}else//如果没有数据{if (ptr->next == NULL)//尚无开空间,开新空间{head = ptr;//记录前一个数据存储空间ptr->next = (date*)malloc(sizeof(date));//开辟一个存储空间ptr = ptr->next;ptr->next = NULL;//初始化部分变量ptr->prev = head;//记录上一个数据ptr->flag = false;}else{ptr = ptr->next;//还有数据只想下一个数据存储空间}}}}


#first为全局变量意为第一个date类型数据  定义为date first;
沿着*next寻找空的数据,找到则分配存储空间,将有内容标志初始化为false


3.展示数据

遍历整个链表,并将数据打印出来

void display(){date *ptr;ptr = &first;//指向第一个存储空间if (ptr->flag == false){printf("no data in the link list\n");return;}printf("***********************************************\n");printf("Name     Math     Chinese     English     AVG\n");while (true){printf("%-9s%-9d%-12d%-12d%-3d\n", ptr->name, ptr->math, ptr->cna, ptr->eng, ptr->avg);if (ptr->next == NULL)break;else ptr = ptr->next;}printf("**********************************************\n");}

初始化一个*ptr ptr等于first(第一个数据)的地址,通过*next指针遍历整个链表当*next指向空遍历结束

输入数据打印效果如下:




4.查找元素

date* search()//查{date *ptr;ptr = &first;//指向第一个存储空间char name[20];printf("name:\n");fflush(stdin);gets_s(name);while (true){if (strcmp(ptr->name, name) == 0)break;//找到结果结束遍历else if (ptr->next == NULL)///遍历结束未找到结果{printf("no date!\n");return NULL;}else ptr = ptr->next;}printf("check the information\n");printf("***********************************************\n");printf("Name     Math     Chinese     English     AVG\n");printf("%-9s%-9d%-12d%-12d%-3d\n", ptr->name, ptr->math, ptr->cna, ptr->eng, ptr->avg);printf("**********************************************\n\n");return ptr;}


因为后面删,改多需要查询元素,该函数需要在后面进行调用,所以返回一个date类型指针即查找的结果。

date类型指针ptr最初指向first,之后进行遍历直到找到name与输入值相同的项,返回ptr指针(即指向匹配项地址)
查询效果如下:




5.修改链表内的元素

有了查找的基础,修改就非常容易实现了。
只需要查找获取匹配项的指针后,修改其值然后返回即可。
void modify()//改{char k=0;date*ptr;ptr = search();printf("sure?(Y/N)\n");k=_getch();if (k == 'Y' || k == 'y'){printf("name:\n");fflush(stdin);gets_s(ptr->name);printf("Math:\n");scanf_s("%d",&ptr->math);printf("Chinese:\n");scanf_s("%d", &ptr->cna);printf("English:\n", &ptr->eng);scanf_s("%d", &ptr->eng);printf("modify complete!\n");}}


6.删除链表中元素

首先还是需要调用search()函数获取匹配项指针,然后会出现多种情况:
1.*prev不为空时
prev->next=ptr->next
2.若*prev为空 则说明已经是指向第一个数据first first=ptr->next即可
void delitem()//删{date *ptr;ptr = search();if (ptr == NULL)return;//没有搜寻到相关元素printf("Are you sure?(Y/N)\n");char key= _getch();if (key == 'Y' || key == 'y'){if (ptr->prev != NULL){ptr->prev->next = ptr->next;ptr->next->prev = ptr->prev;free(ptr);}else//如果是表头元素将其重新初始化即可{if (ptr->next != NULL){first = *ptr->next;first.prev = NULL;}else{printf("already no data in link list\n");first.flag = false;}}}}




原创粉丝点击