学生教师作业系统c语言,懒猫老师-C语言-链表作业1:学生管理系统(链表练习,链表应用)...

==================

7017422739ad

image.png

7017422739ad

image.png

7017422739ad

image.png

7017422739ad

image.png

7017422739ad

image.png

7017422739ad

image.png

7017422739ad

image.png

7017422739ad

image.png

7017422739ad

image.png

7017422739ad

image.png

7017422739ad

image.png

我测试了一下,就有一个函数不能用,其余的都是正常的,学到了不少东西啊

还有,判断2个字符串,是否相同,得用strcmp函数,而不是 ==

//============================================================================

// Name : LinkBlank.cpp

// Author :

// Version :

// Copyright : Your copyright notice

// Description : Hello World in C++, Ansi-style

//============================================================================

#include

#include

#include

#include

#include

#define NO_LENGTH 20

#define NAME_LENGTH 11

/* 定义学生结构体的数据结构 */

typedef struct Student{

char studentNo[NO_LENGTH];

char studentName[NAME_LENGTH];

}st;

/* 定义每条记录或节点的数据结构 */

typedef struct node

{

struct Student data; //数据域

struct node *next; //指针域

}Node, *Link; //Node为node类型的别名,Link为node类型的指针别名

//定义提示菜单

void myMenu(){

printf(" * * * * * * * * * 菜 单 * * * * * * * * * *\n");

printf(" 1 增加学生记录 2 删除学生记录 \n");

printf(" 3 查找学生记录 4 修改学生记录 \n");

printf(" 5 统计学生人数 6 显示学生记录 \n");

printf(" 7 退出系统 \n");

printf(" * * * * * * * * * * * * * * * * * * * * * * * *\n");

}

void inputStudent(Link l){

printf("请输入学生学号:");

scanf("%s", l->data.studentNo);

printf("请输入学生的姓名:");

scanf("%s", l->data.studentName);

//每个新创建的节点的next域都初始化为NULL

l->next = NULL;

}

//这个是干嘛的???

void inputStudentNo(char s[], char no[]){ //数组名当做函数形参

printf("请输入要%s的学生学号:", s); //char s中的s,代表 修改 查询,删除,等字样

scanf("%s", no);

}

//作业内容,我自己编写的

void displayNode(Link head){

// 填写代码,根据传入的链表head头指针,扫描链表显示所有节点的信息

Link p;

p = head->next;

while (p!=NULL)

{

printf("学生的学号是:%s \n", p->data.studentNo);

printf("学生的姓名是:%s \n", p->data.studentName);

p = p->next;

}

}

/* 增加学生记录 */

bool addNode(Link head){

Link p, q; //p,q两个节点一前一后

Link node; //node指针指向新创建的节点

node = (Link)malloc(sizeof(Node));

inputStudent(node); //传入一个节点,手动输入学生学号和学生姓名这2个数据,传入到结点node当中!,有意思的操作!

q = head;

p = head->next; //q指向head后面的第一个有效节点

if (head->next == NULL)

//链表为空时

head->next = node;

else { //当链表不为空,说明链表本身就有数据的时候,执行下段代码。。

//循环访问链表中的所有节点

while (p != NULL){

if (node->data.studentNo < p->data.studentNo){

//如果node节点的学号比p节点的学号小,则插在p的前面,完成插入后,提前退出子程序

q->next = node;

node->next = p;

return true;

}

else{

//如果node节点的学号比p节点的学号大,继续向后移动指针(依然保持pq一前一后)q....p 这样的顺序。

q = p;

p = p->next;

}

}

//如果没能提前退出循环,则说明之前没有插入,那么当前node节点的学号是最大值,此时插在链表的最后面

q->next = node;

}

return true;

}

//老师留下的作业,自己完成需要

bool deleteNode(Link head){

// 按照给定的学号删除学生记录,如果删除成功返回true,如果没找到学号返回false

//输入要处理的学号

char no[NO_LENGTH];

inputStudentNo("删除", no);

Link p, q;

if (head==NULL ||head->next==NULL ) //如果链表没有数据,返回false

{

return false;

}

q = head;

p = head->next; //初始化。q,p两个指针,一前一后。

while (p!=NULL)

{

if (strcmp(p->data.studentNo, no) == 0) //判断2个字符串相同,不能用==,而应该用strcmp函数!

{

q->next = p->next;

free(p);

return true;

}

else //如果没有找到,就让两个指针,同时往下一个结点去遍历

{

q = p;

p = p->next;

}

}

//如果循环遍历结束,都没有找到相对应的学号,说过指定学号不在链表当中

return false;

}

//老师留下的作业,自己完成需要,查找学生记录

bool queryNode(Link head){

// 按照给定的学号查询学生记录,如果查询成功返回true,如果没找到学号返回false

//输入要处理的学号

char no[NO_LENGTH];

inputStudentNo("查找", no);

//printf("要查找的数组序号是:%s \n", no);

Link p;

p = head->next;

while (p!=NULL)

{

/*printf("学生的姓名是: %s \n", p->data.studentNo);

printf("学生的姓名是: %s \n", p->data.studentName);*/

if (strcmp(p->data.studentNo,no)==0 ) //判断2个字符串相同,不能用==,而应该用strcmp函数!

{

printf("成功了!该学生的姓名是: %s", p->data.studentName);

return true;

}

p = p->next;

}

//如果循环结束了,说明没有找到

return false;

}

//老师留下的作业,自己完成需要

bool modifyNode(Link head){

// 按照给定的学号找到学生记录节点,如果修改成功返回true,如果没找到学号返回false

//输入要处理的学号-----------只修改学号,不修改姓名?还是2者都可以随便修改?

char no[NO_LENGTH];

inputStudentNo("修改", no);

if (head == NULL || head->next == NULL) //如果链表没有数据,返回false

{

return false;

}

Link p;

p = head->next;

while (p != NULL)

{

if (strcmp(p->data.studentNo, no) == 0) //当找到用户的学号的时候,

{

printf("学生的姓名是: %s \n", p->data.studentName);

scanf("把此学生姓名修改为: %s \n", p->data.studentName);

return true;

}

p = p->next;

}

return false;

}

//老师留下的作业,自己完成需要

int countNode(Link head){

//统计学生人数,扫描链表统计节点个数,返回节点数

Link p;

int count = 0;

p = head->next;

if (head == NULL || head->next == NULL) //如果链表没有数据,返回false

{

return false;

}

while (p!=NULL)

{

p = p->next;

count++;

}

//填充代码

return count; //注意count的初始值和返回值之间的关系。

}

//老师留下的作业,自己完成需要,我自己写的不知道是否可以。

int clearLink(Link head){

Link q, p;

//遍历链表,用free语句删除链表中用malloc建立起的所有的节点

if (head == NULL || head->next == NULL) //如果链表没有数据,返回false

{

return false;

}

while (head->next!=NULL)

{

q = head;

head = head->next;

free(q);

}

return true;

}

int main() {

int select;

int count;

Link head; // 定义链表

//建立head头结点,在这个程序中head指向头结点,头结点data部分没有内容,其后续节点才有真正的数据

head = (Link)malloc(sizeof(Node));

head->next = NULL;

while (1)

{

myMenu();

printf("\n请输入你的选择(0-7):"); //显示提示信息

scanf("%d", &select);

switch (select)

{

case 1:

//增加学生记录

if (addNode(head))

printf("成功插入一个学生记录。\n\n");

break;

case 2:

//删除学生记录

if (deleteNode(head))

printf("成功删除一个学生记录。\n\n");

else

printf("没有找到要删除的学生节点。\n\n");

break;

case 3:

//查询学生记录

if (queryNode(head))

printf("成功找到学生记录。\n\n");

else

printf("没有找到要查询的学生节点。\n\n");

break;

case 4:

//修改学生记录

if (modifyNode(head))

printf("成功修改一个学生记录。\n\n");

else

printf("没有找到要修改的学生节点。\n\n");

break;

case 5:

//统计学生人数

count = countNode(head);

printf("学生人数为:%d\n\n", count);

break;

case 6:

//显示学生记录

displayNode(head);

break;

case 7:

//退出前清除链表中的所有结点

clearLink(head);

return 0;

default:

printf("输入不正确,应该输入0-7之间的数。\n\n");

break;

}

}

return 0;

}

=========

我在网上,找到了一个学生的学习笔记,写的比我的好,细节很到位

网址:https://www.yuque.com/jason2018/euoi7a/mxiowo

//============================================================================

// Name : LinkBlank.cpp

// Author :

// Version :

// Copyright : Your copyright notice

// Description : Hello World in C++, Ansi-style

//============================================================================

#include

#include

#include

#include

#include

#define NO_LENGTH 20

#define NAME_LENGTH 11

/* 定义学生结构体的数据结构 */

typedef struct Student{

char studentNo[NO_LENGTH];

char studentName[NAME_LENGTH];

}st;

/* 定义每条记录或节点的数据结构 */

typedef struct node

{

struct Student data; //数据域

struct node *next; //指针域

}Node, *Link; //Node为node类型的别名,Link为node类型的指针别名

//定义提示菜单

void myMenu(){

printf(" * * * * * * * * * 菜 单 * * * * * * * * * *\n");

printf(" 1 增加学生记录 2 删除学生记录 \n");

printf(" 3 查找学生记录 4 修改学生记录 \n");

printf(" 5 统计学生人数 6 显示学生记录 \n");

printf(" 7 退出系统 \n");

printf(" * * * * * * * * * * * * * * * * * * * * * * * *\n");

}

void inputStudent(Link l){

printf("请输入学生学号:");

scanf("%s", l->data.studentNo);

printf("请输入学生的姓名:");

scanf("%s", l->data.studentName);

//每个新创建的节点的next域都初始化为NULL

l->next = NULL;

}

//这个是干嘛的???

void inputStudentNo(char s[], char no[]){ //数组名当做函数形参

printf("请输入要%s的学生学号:", s); //char s中的s,代表 修改 查询,删除,等字样

scanf("%s", no);

}

//作业内容,我自己编写的

void displayNode(Link head){

// 填写代码,根据传入的链表head头指针,扫描链表显示所有节点的信息

Link p;

p = head->next;

while (p!=NULL)

{

printf("学生的学号是:%s \n", p->data.studentNo);

printf("学生的姓名是:%s \n", p->data.studentName);

p = p->next;

}

}

/* 增加学生记录 */

bool addNode(Link head){

Link p, q; //p,q两个节点一前一后

Link node; //node指针指向新创建的节点

node = (Link)malloc(sizeof(Node));

inputStudent(node); //传入一个节点,手动输入学生学号和学生姓名这2个数据,传入到结点node当中!,有意思的操作!

q = head;

p = head->next; //q指向head后面的第一个有效节点

if (head->next == NULL)

//链表为空时

head->next = node;

else { //当链表不为空,说明链表本身就有数据的时候,执行下段代码。。

//循环访问链表中的所有节点

while (p != NULL){

if (node->data.studentNo < p->data.studentNo){

//如果node节点的学号比p节点的学号小,则插在p的前面,完成插入后,提前退出子程序

q->next = node;

node->next = p;

return true;

}

else{

//如果node节点的学号比p节点的学号大,继续向后移动指针(依然保持pq一前一后)q....p 这样的顺序。

q = p;

p = p->next;

}

}

//如果没能提前退出循环,则说明之前没有插入,那么当前node节点的学号是最大值,此时插在链表的最后面

q->next = node;

}

return true;

}

//老师留下的作业,自己完成需要

bool deleteNode(Link head){

// 按照给定的学号删除学生记录,如果删除成功返回true,如果没找到学号返回false

//输入要处理的学号

char no[NO_LENGTH];

inputStudentNo("删除", no);

Link p, q;

if (head==NULL ||head->next==NULL ) //如果链表没有数据,返回false

{

return false;

}

q = head;

p = head->next; //初始化。q,p两个指针,一前一后。

while (p!=NULL)

{

if (strcmp(p->data.studentNo, no) == 0) //判断2个字符串相同,不能用==,而应该用strcmp函数!

{

q->next = p->next;

free(p);

return true;

}

else //如果没有找到,就让两个指针,同时往下一个结点去遍历

{

q = p;

p = p->next;

}

}

//如果循环遍历结束,都没有找到相对应的学号,说过指定学号不在链表当中

return false;

}

//插入一个学生记录

void insertNode(Link head, Link newNode)

{

Link p, q;

bool flag = false; //是否插入成功

p = head;

q = head->next;

//如果是空链表

if (head->next == NULL)

{

head->next = newNode;

flag = true;

}

else

{

//不是空链表

while (q != NULL)

{

/*

① str1小于str2,返回负值或者-1(VC返回-1);

② str1等于str2,返回0;

③ str1大于str2,返回正值或者1(VC返回1);

*/

if (strcmp(newNode->data.studentNo, q->data.studentNo) < 0) //如果newnode小于studentNo,就进行下列操作。。

{

p->next = newNode; //如果不明白,画一下图,立马就明白了。

newNode->next = q;

flag = true;

break;

}

else //如果新增的学生序号大于q->学生序号,那么就顺着循序往下移动。精妙的操作

{

p = q;

q = q->next;

}

}

}

if (q == NULL && flag == false) //如果q指针带头了,或者flag=false,那么久

{

p->next = newNode;

}

}

//老师留下的作业,自己完成需要,查找学生记录

bool queryNode(Link head){

// 按照给定的学号查询学生记录,如果查询成功返回true,如果没找到学号返回false

//输入要处理的学号

char no[NO_LENGTH];

inputStudentNo("查找", no);

//printf("要查找的数组序号是:%s \n", no);

Link p;

p = head->next;

while (p!=NULL)

{

/*printf("学生的姓名是: %s \n", p->data.studentNo);

printf("学生的姓名是: %s \n", p->data.studentName);*/

if (strcmp(p->data.studentNo,no)==0 ) //判断2个字符串相同,不能用==,而应该用strcmp函数!

{

printf("成功了!该学生的姓名是: %s", p->data.studentName);

return true;

}

p = p->next;

}

//如果循环结束了,说明没有找到

return false;

}

//老师留下的作业,自己完成需要

bool modifyNode(Link head){

// 按照给定的学号找到学生记录节点,如果修改成功返回true,如果没找到学号返回false

//输入要处理的学号-----------只修改学号,不修改姓名?还是2者都可以随便修改?

char no[NO_LENGTH];

char no_new[NO_LENGTH]; //新学号

char name_new[NAME_LENGTH]; //新姓名

int select; //功能选择

Link p, q;

inputStudentNo("修改", no);

printf("请输入需要修改的项目: 1 学号 2 姓名\n");

scanf("%d", &select);

p = head;

q = head->next;

while (q != NULL)

{

if (strcmp(q->data.studentNo, no) == 0) //当在链表中遍历到该学生学号的时候,

{

if (select == 1)

{

p->next = q->next;

q->next = NULL;

printf("请输入该学生的新学号:");

scanf("%s", no_new);

strcpy(q->data.studentNo, no_new);

insertNode(head, q);

}

else

{

printf("请输入该学生的新姓名:");

scanf("%s", name_new);

strcpy(q->data.studentName, name_new);

}

return true;

}

else

{

p = q;

q = q->next;

}

}

return false;

}

//老师留下的作业,自己完成需要

int countNode(Link head){

//统计学生人数,扫描链表统计节点个数,返回节点数

Link p;

int count = 0;

p = head->next;

if (head == NULL || head->next == NULL) //如果链表没有数据,返回false

{

return false;

}

while (p!=NULL)

{

p = p->next;

count++;

}

//填充代码

return count; //注意count的初始值和返回值之间的关系。

}

//老师留下的作业,自己完成需要,我自己写的不知道是否可以。

int clearLink(Link head){

Link q, p;

//遍历链表,用free语句删除链表中用malloc建立起的所有的节点

if (head == NULL || head->next == NULL) //如果链表没有数据,返回false

{

return false;

}

while (head->next!=NULL)

{

q = head;

head = head->next;

free(q);

}

return true;

}

int main() {

int select;

int count;

Link head; // 定义链表

//建立head头结点,在这个程序中head指向头结点,头结点data部分没有内容,其后续节点才有真正的数据

head = (Link)malloc(sizeof(Node));

head->next = NULL;

while (1)

{

myMenu();

printf("\n请输入你的选择(0-7):"); //显示提示信息

scanf("%d", &select);

switch (select)

{

case 1:

//增加学生记录

if (addNode(head))

printf("成功插入一个学生记录。\n\n");

break;

case 2:

//删除学生记录

if (deleteNode(head))

printf("成功删除一个学生记录。\n\n");

else

printf("没有找到要删除的学生节点。\n\n");

break;

case 3:

//查询学生记录

if (queryNode(head))

printf("成功找到学生记录。\n\n");

else

printf("没有找到要查询的学生节点。\n\n");

break;

case 4:

//修改学生记录

if (modifyNode(head))

printf("成功修改一个学生记录。\n\n");

else

printf("没有找到要修改的学生节点。\n\n");

break;

case 5:

//统计学生人数

count = countNode(head);

printf("学生人数为:%d\n\n", count);

break;

case 6:

//显示学生记录

displayNode(head);

break;

case 7:

//退出前清除链表中的所有结点

clearLink(head);

return 0;

default:

printf("输入不正确,应该输入0-7之间的数。\n\n");

break;

}

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值