上一次我们一起学习链表的创建以及链表的一些常用操作,并将链表与数组进行了对比,分析了这两个存储方式各自的利弊。今天让我们一起学习一下如何使用链表吧!
使用链表写这些管理系统相较与数组有着很大的优势。优势一:管理系统要能动态存储信息随时可以增添新的信息,数组只能先确定人数而链表可以做到这一点。优势二:管理系统经常进行增删查改等操作,链表对于这些操作的时间复杂度远低于数组,可以加快程序的运行速度。
说完链表在这个项目中的优点,接下来就让我们一起来看看怎么用链表去实现学生管理系统的各个功能吧!
用链表实现学生管理系统的各个功能其实很简单,只要你掌握了对链表的一些常用操作,这个学生管理系统就能手拿把掐了。言归正传,既然我们要写的是学生管理系统那肯定少不了学生的信息,所以首先我们要先定义一个学生结构体,代码如下
//创建学生信息
typedef struct student
{int age;//年龄
char spe[20];//专业
char name[20];//姓名
}stu;
我们用typedef来修饰一下这个学生结构体便于后面的调用,这个学生结构体用来存储学生专业,年龄,姓名等信息 。其中有个细节就是因为结构体对齐的原因所以我们在定义结构体的时候尽量将字节数少的部分放在前面定义,这样可以节约内存空间,会减少资源浪费。
接下来我们来创建一个函数来供用户选择使用哪一个功能并为其做好相应的界面。
void PriInterface(void)
{
printf("/*************************************学生管理系统****************************************/\n");
printf("0.退出系统\n");
printf("1.查看学生信息\t");
printf("2.添加学生信息\n");
printf("3.删除学生信息\t");
printf("4.修改学生信息\n");
printf("请根据您的需求输入相应的数字:");
}
int Key()
{
int temp = 0;
scanf("%d", &temp);
switch (temp)
{
case 0:
printf("退出成功!");
return -1;
break;case 1:
SearchInterface();//查找学生信息对应界面函数
Search();//查找学生信息对应的操作函数
break;case 2:
AddInterface();//添加学生信息对应界面函数
Add();//添加学生信息对应的操作函数
break;
case 3:
DeleteInterface();//删除学生信息对应界面函数
Delete();//删除学生信息对应的操作函数
break;
case 4:
ModInterface();//修改学生信息对应界面函数
mod();//修改学生信息对应的操作函数
break;
}return 0;
}
我们学了c语言都知道我们想要实现多分支选择的时候就要用到switch函数来实现了。
做好了供用户选择的函数,接下来让我们一个一个看看各个功能是如何实现的吧!
查找功能: 查找功能就是将用户输入的信息与每个结点中的数据域data存储的对应信息比较,如果相同就打印不同就往后查找,如果遍历了整个链表都没找到对应的结点则进行错误处理。
void NameprintList(struct simpleList* headNode, char* name)
{
int a = 0;
struct simpleList* pMove = headNode->next;
while (pMove != NULL)
{
if (strcmp(name, pMove->data.name) == 0)
{
printf("%s\t\t%d\t\t%s\n", pMove->data.name, pMove->data.age, pMove->data.spe);
}
pMove = pMove->next;
a++;
}if (pMove == NULL && a == 0)
{
printf("未找到该学生,请您正确输入学生姓名!");
}
}
void Search(void)
{
int temp = 0;
scanf("%d", &temp);char tempname[20] = { 0 };
int tempage = 0;
switch (temp)
{
case 1:
printf("请输入想要查找学生的姓名:");
scanf("%s", tempname);
NameprintList(List, tempname);//按照姓名打印函数
break;case 2:
printf("请输入想要查找学生的年龄:");
scanf("%d", &tempage);
AgeprintList(List, tempage);//按照年龄打印函数
break;
}
}
当然我们为了使用者的方便还要设计相应的界面来提醒用户该如何进行操作:
void SearchInterface(void)
{
printf("/*********************************查看学生信息*****************************************/\n");
printf("1.按姓名查找\n");
printf("2.按年龄查找\n");
printf("请您按照需求输入相应的数字:");
}
这就简单的完成了一个查找功能,这里我只给大家展示了按照名字来查找函数的实现来供大家参考,大家还可以进行简单的改写实现年龄查找,专业查找等方式。
增加功能:增加功能就是我们在上一节讲到的头插法用来插入新的学生信息。具体代码实现如下:
void insertNode(struct simpleList* headNode, stu data)
{
struct simpleList* newNode = createNode(data);
newNode->next = headNode->next;
headNode->next = newNode;
}
void Add(void)
{
stu temp = { 0 };
scanf("%s %d %s", temp.name, &temp.age, temp.spe);
insertNode(List, temp);
printf("录入成功!\n");
printList(List);
}
还有其对应的界面函数实现如下:
void AddInterface(void)
{
printf("/*********************************添加学生信息*****************************************/\n");
printf("请您按顺序输入想要添加的学生信息:\n");
printf("姓名 年龄 专业\n");
}
删除功能:删除功能也是我们链表的常用操作之一,这里就不做过多赘述了,不知道的同学可以去看我上一篇文章。具体实现代码如下:
void DeleteName(struct simpleList* headNode, char* name)
{
struct simpleList* posNode = headNode->next;
struct simpleList* posFronNode = headNode;
while (posNode != NULL && strcmp(name, posNode->data.name) != 0)
{
posFronNode = posNode;
posNode = posNode->next;
}
if (posNode == NULL)
{
printf("未找到对应信息,无法删除");
}
else
{
posFronNode->next = posNode->next;
free(posNode);
posNode = NULL;
printf("成功删除该学生信息");
}
}
void Delete(void)
{
int temp = 0;
scanf("%d", &temp);char tempname[20] = { 0 };
switch (temp)
{
case 1:
printf("请输入想要删除学生的姓名:");
scanf("%s", tempname);
DeleteName(List, tempname);//按照姓名打印函数
break;case 2:
break;
}
}
对应的界面代码:
void DeleteInterface(void)
{
printf("/*********************************删除学生信息*****************************************/\n");
printf("1.按姓名删除\n");
printf("2.按年龄删除\n");
printf("请您按照需求输入相应的数字:");
}
修改功能:修改功能就是通过创建一个临时的位置结点去遍历整个链表,找到对应的结点然后通过结构体指针去改变该地址存储的数据,实现修改功能。下面奉上代码:
void mod(void)
{
int temp = 0;
scanf("%d", &temp);char tempname[20] = { 0 };
switch (temp)
{
case 1:
printf("请输入想要修改学生的姓名:");
scanf("%s", tempname);
modnewbyname(List, tempname);//按照姓名修改信息函数
break;case 2:
break;
}
}
void modnewbyname(struct simpleList* headNode, char* name)
{
struct simpleList* posNode = headNode->next;
while (posNode != NULL && strcmp(name, posNode->data.name) != 0)
{
posNode = posNode->next;
}
if (posNode == NULL)
{
printf("未找到该学生,请正确输入学生信息!");
}
else
{
int temp = 0;
char tempname[20] = { 0 };
int tempage = 0;
char tempspe[20] = { 0 };
printf("请输入数字,1.表示修改名字 2.表示修改年龄 3.表示修改专业");
scanf("%d", &temp);
switch (temp)
{
case 1:
printf("请输入修改的新名字:");
scanf("%s", tempname);
strcpy(posNode->data.name, tempname);
printf("修改成功!");
break;
case 2:
printf("请输入修改的新年龄:");
scanf("%d", &tempage);
posNode->data.age = tempage;
printf("修改成功!");
break;
case 3:
printf("请输入修改的新专业:");
scanf("%d", &tempspe);
strcpy(posNode->data.spe, tempspe);
printf("修改成功!");
break;
}
}
}
对应的界面代码:
void ModInterface(void)
{
printf("/*********************************修改学生信息*****************************************/\n");
printf("1.按姓名查找修改\n");
printf("2.按年龄查找修改\n");
printf("请您按照需求输入相应的数字:");
}
我用链表简单实现了一个学生管理系统仅供大家参考,大家可以根据需求去完善内容,本人也是编程小白,有错误的地方希望大佬们能指正!下面附上完整的代码以及运行的结果:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <windows.h>struct simpleList* List = NULL;
//创建学生信息
typedef struct student
{
char spe[20];//专业
int age;//年龄
char name[20];//姓名
}stu;//创建链表结构体(指针指向下一个结构体所以是struct simpleList*类型的指针)
struct simpleList
{
stu data;//数据域
struct simpleList* next;//指针域
};//创建头结点
struct simpleList* createHead()
{
struct simpleList* headNode = (struct simpleList*)malloc(sizeof(struct simpleList));
if (headNode == NULL)
{
printf("头结点内存分配失败");
return NULL;
}
headNode->next = NULL;
return headNode;
}//创建结点
struct simpleList* createNode(stu data)
{
struct simpleList* newNode = (struct simpleList*)malloc(sizeof(struct simpleList));
if (newNode == NULL)
{
printf("结点内存分配失败");
return NULL;
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}//头插法
void insertNode(struct simpleList* headNode, stu data)
{
struct simpleList* newNode = createNode(data);
newNode->next = headNode->next;
headNode->next = newNode;
}void printList(struct simpleList* headNode)
{
struct simpleList* pMove = headNode->next;
while (pMove != NULL)
{
printf("%s\t\t%d\t\t%s\n", pMove->data.name, pMove->data.age, pMove->data.spe);
pMove = pMove->next;
}
}//打印链表
void NameprintList(struct simpleList* headNode, char* name)
{
int a = 0;
struct simpleList* pMove = headNode->next;
while (pMove != NULL)
{
if (strcmp(name, pMove->data.name) == 0)
{
printf("%s\t\t%d\t\t%s\n", pMove->data.name, pMove->data.age, pMove->data.spe);
}
pMove = pMove->next;
a++;
}if (pMove == NULL && a == 0)
{
printf("未找到该学生,请您正确输入学生姓名!");
}
}//打印链表
void AgeprintList(struct simpleList* headNode, int age)
{
int a = 0;
struct simpleList* pMove = headNode->next;
while (pMove != NULL)
{
if (age == pMove->data.age)
{
printf("%s\t\t%d\t\t%s\n", pMove->data.name, pMove->data.age, pMove->data.spe);
}
pMove = pMove->next;
a++;
}if (pMove == NULL && a == 0)
{
printf("未找到该学生,请您正确输入学生年龄!");
}
}//指定位置删除结点
void DeleteName(struct simpleList* headNode, char* name)
{
struct simpleList* posNode = headNode->next;
struct simpleList* posFronNode = headNode;
while (posNode != NULL && strcmp(name, posNode->data.name) != 0)
{
posFronNode = posNode;
posNode = posNode->next;
}
if (posNode == NULL)
{
printf("未找到对应信息,无法删除");
}
else
{
posFronNode->next = posNode->next;
free(posNode);
posNode = NULL;
printf("成功删除该学生信息");
}
}void modnewbyname(struct simpleList* headNode, char* name)
{
struct simpleList* posNode = headNode->next;
while (posNode != NULL && strcmp(name, posNode->data.name) != 0)
{
posNode = posNode->next;
}
if (posNode == NULL)
{
printf("未找到该学生,请正确输入学生信息!");
}
else
{
int temp = 0;
char tempname[20] = { 0 };
int tempage = 0;
char tempspe[20] = { 0 };
printf("请输入数字,1.表示修改名字 2.表示修改年龄 3.表示修改专业");
scanf("%d", &temp);
switch (temp)
{
case 1:
printf("请输入修改的新名字:");
scanf("%s", tempname);
strcpy(posNode->data.name, tempname);
printf("修改成功!");
break;
case 2:
printf("请输入修改的新年龄:");
scanf("%d", &tempage);
posNode->data.age = tempage;
printf("修改成功!");
break;
case 3:
printf("请输入修改的新专业:");
scanf("%d", &tempspe);
strcpy(posNode->data.spe, tempspe);
printf("修改成功!");
break;
}
}
}void PriInterface(void)
{
printf("/*************************************学生管理系统****************************************/\n");
printf("0.退出系统\n");
printf("1.查看学生信息\t");
printf("2.添加学生信息\n");
printf("3.删除学生信息\t");
printf("4.修改学生信息\n");
printf("请根据您的需求输入相应的数字:");
}void SearchInterface(void)
{
printf("/*********************************查看学生信息*****************************************/\n");
printf("1.按姓名查找\n");
printf("2.按年龄查找\n");
printf("请您按照需求输入相应的数字:");
}void AddInterface(void)
{
printf("/*********************************添加学生信息*****************************************/\n");
printf("请您按顺序输入想要添加的学生信息:\n");
printf("姓名 年龄 专业\n");
}void DeleteInterface(void)
{
printf("/*********************************删除学生信息*****************************************/\n");
printf("1.按姓名删除\n");
printf("2.按年龄删除\n");
printf("请您按照需求输入相应的数字:");
}void ModInterface(void)
{
printf("/*********************************修改学生信息*****************************************/\n");
printf("1.按姓名查找修改\n");
printf("2.按年龄查找修改\n");
printf("请您按照需求输入相应的数字:");
}void Search(void)
{
int temp = 0;
scanf("%d", &temp);char tempname[20] = { 0 };
int tempage = 0;
switch (temp)
{
case 1:
printf("请输入想要查找学生的姓名:");
scanf("%s", tempname);
NameprintList(List, tempname);//按照姓名打印函数
break;case 2:
printf("请输入想要查找学生的年龄:");
scanf("%d", &tempage);
AgeprintList(List, tempage);//按照年龄打印函数
break;
}
}void Add(void)
{
stu temp = { 0 };
scanf("%s %d %s", temp.name, &temp.age, temp.spe);
insertNode(List, temp);
printf("录入成功!\n");
printList(List);
}void Delete(void)
{
int temp = 0;
scanf("%d", &temp);char tempname[20] = { 0 };
switch (temp)
{
case 1:
printf("请输入想要删除学生的姓名:");
scanf("%s", tempname);
DeleteName(List, tempname);//按照姓名打印函数
break;case 2:
break;
}
}void mod(void)
{
int temp = 0;
scanf("%d", &temp);char tempname[20] = { 0 };
switch (temp)
{
case 1:
printf("请输入想要修改学生的姓名:");
scanf("%s", tempname);
modnewbyname(List, tempname);//按照姓名修改信息函数
break;case 2:
break;
}
}int Key()
{
int temp = 0;
scanf("%d", &temp);
switch (temp)
{
case 0:
printf("退出成功!");
return -1;
break;case 1:
SearchInterface();//查找学生信息对应界面函数
Search();//查找学生信息对应的操作函数
break;case 2:
AddInterface();//添加学生信息对应界面函数
Add();//添加学生信息对应的操作函数
break;
case 3:
DeleteInterface();//删除学生信息对应界面函数
Delete();//删除学生信息对应的操作函数
break;
case 4:
ModInterface();//修改学生信息对应界面函数
mod();//修改学生信息对应的操作函数
break;
}return 0;
}int main(void)
{
//创建链表用来存储系统信息
List = createHead();PriInterface();//主界面函数
while (Key() != -1)
{
Key();//按键函数
}
system("cls");
return 0;
}
将信息用文件来存储就是一个不错的选择,我没有写将信息存入文件的操作,大家可以自己发挥。
该程序仅供参考,有任何问题大家都可以发在评论区,我们一起探讨!我会持续更新我学习中遇到的困难以及学习的一些感悟,让我们一起学习,早日成为编程高手吧!