前言:
上一节通过学习单链表,知道单链表的是随机存取结构,要获取元素的元素必须从头指针出发顺序查找,因此也称为顺序存取的存取结构,使用单链表可以克服数组链表需要预先知道数据大小的缺点,实现灵活的动态内存管理。
这里我们用C语言结合单链表来实现一个可以实现增删改查的学生管理系统。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//定义结构属性
struct MM
{
char name[20];
int age;
int num;
char addr[20];
};
struct Node*list = NULL;
struct Node
{
struct MM data;
struct Node*next;
};
1.创建表头:描述最初状态
struct Node*createList()
{
//创建链表就是创建表头
//创建表头就是创建结构体变量
struct Node*headNode = (struct Node*)malloc(sizeof(struct Node));
//表头不给数据初始化
headNode->next = NULL;
return headNode;
}
2.创建结点:为插入数据做准备,把数据加工成结构体变量
struct Node*creatNode(struct MM data)
{
struct Node*newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
3.表头法插入
void insertByHead(struct Node*headNode, struct MM data)
{
//插入前需要创建节点
struct Node*newNode = creatNode(data);
newNode->next = headNode->next;
headNode->next = newNode;
}
4.指定位置删除 --以数据为指定
void deleteAppoinByName(struct Node*headNode, char *name)
{
//相邻的两个指针
struct Node*posFrontNode = headNode;
struct Node*posNode = headNode->next;
//找指定位置
while (posNode != NULL&&strcmp(posNode->data.name, name))
{
posFrontNode = posNode;
posNode = posFrontNode->next;
}
//分析查找的结果
//循环退出有两种结果:posNode==NULL,posNode->data==posData;
if (posNode == NULL)
{
printf("未找到指定位置无法删除");
return;
}
else
{
posFrontNode->next = posNode->next;
free(posNode);
posNode = NULL;
}
}
5.查找函数
struct Node*serchInfoByName(struct Node*headNode, char *name)
{
struct Node*pMove = headNode;
while (pMove != NULL&strcmp(pMove->data.name, name))
{
pMove = pMove->next;
}
return pMove;
}
6.打印链表:
void printList(struct Node*headNode)
{
struct Node*pMove = headNode->next;//因为有表头,所以从表头下一个结点开始打印
printf("姓名\t年龄\t编号\t住址\n");
while (pMove != NULL)
{
//printf("%d\t", pMove->data);
printf("%s\t%d\t%d\t%s\n", pMove->data.name, pMove->data.age,
pMove->data.num, pMove->data.addr);
pMove = pMove->next;
}
printf("\n");
}
7.删除功能:删除所有相同姓名的人
void deleteByName(struct Node*headNode, char *name)
{
while (serchInfoByName(headNode, name) != NULL)
{
//懂得利用之前写好的删除函数
deleteAppoinByName(headNode, name);
}
}
8.界面
void menu()
{
printf("-----------------【学生管理系统】------------\n");
printf("\t0.退出系统!\n");
printf("\t1.登录学生信息!\n");
printf("\t2.浏览学生信息!\n");
printf("\t3.查找学生信息!\n");
printf("\t4.删除信息!\n");
printf("\t5.修改学生信息!\n");
printf("\t6.删除所有姓名相同的学生!");
printf("---------------------------------------------\n");
printf("请输入0-6\n");
}
9.用户选择菜单
void keyDown()
{
int choice = 0;
struct MM data;
struct Node*result = NULL;
scanf("%d", &choice);
switch (choice)
{
case 0:
printf("推出成功!\n");
system("pause");
exit(0);
break;
case 1:
printf("请输入(name,age,num,addr):");
scanf("%s%d%d%s", data.name, &data.age, &data.num, data.addr);
insertByHead(list, data);
break;
case 2:
printList(list);
break;
case 3:
printf("请输入需要查询的学生姓名!");
scanf("%s", data.name);
result = serchInfoByName(list, data.name);
if (result = NULL)
{
printf("未找到信息!");
}
else
{
printf("姓名\t年龄\t编号\t住址\n");
printf("%s\t%d\t%d\t%s\n", result->data.name,
result->data.age, result->data.num, result->data.addr);
}
break;
case 4:
printf("请输入删除的学生信息!");
scanf("%s", data.name);
deleteAppoinByName(list, data.name);
break;
case 5:
printf("请输入要修改学生的信息!");
scanf("%s", data.name);
result = serchInfoByName(list, data.name);
if (result == NULL)
{
printf("未找到相关信息,无法修改!");
}
else
{
printf("请输入新的信息(name,age,num,addr):");
scanf("%s%d%d%s", result->data.name, &result->data.age,
&result->data.num, result->data.addr);
//字符串访问不需要&,整型数据访问需要&
printf("修改成功!");
}
break;
case 6:
printf("请输入要删除学生的信息!");
scanf("%s", data.name);
deleteAppoinByName(list, data.name);
break;
default:
printf("输入错误!");
break;
}
}
int main()
{
list = createList();
while (1)
{
menu();
keyDown();
system("pause");
system("cls"); //用于刷新屏幕
}
system("pause");
return 0;
}
总结: 单链表的可是实现数据的间断性存储,可以节约内存空间。只需要用基本的单链表知识就可以实现一个管理系统了,快动手试一下吧!