链表作业1:学生管理系统

要求:完成学生管理的链表程序。具有学生信息增加、显示、修改、删除、查找、学生人数统计功能的程序。增加学生信息时,按照学号排序;根据给定的学号,可以完成指定学号的修改、删除和查找功能。

目录

一.定义数据结构

二.主函数

三.执行功能的函数 

四,完整代码


一.定义数据结构

1)定义学生结构体的数据结构

typedef struct Student{
   char studentName[NAME_LENGTH];//姓名
   char studentNo[NO_LENGTH];//学号
   char studentgender[GENDER_LENGTH];//性别
   char studentleague[LEAGUE_LENGTH];//政治面貌
}st;

2)定义每条记录或节点的数据结构

typedef struct node{
  struct Student data;//数据域,是Student结构类型的
  struct node*next;//指针域,指向node类型的结构
}Node,*Link;

二.主函数

1)创建头指针

2)输入选择的程序功能

int main(){
 Link head;
 int select;
 head=(Link)malloc(sizef(Node));
 head->next=NULL;
 while(1){//除非手动选择退出循环,否则一直继续
 myMenu();
 printf("请输入你的选择(1~7)");
 scanf("%d",&select);
 switch(select){
    case 1://增加学生记录
            if (addNode(head))
		    printf("成功插入一个学生记录。\n\n");
    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;
}

三.执行功能的函数 

所有函数中要比较两个字符串是否相同,要调用strcmp函数,不能直接用==比较

替换调用strcpy函数

1)每次操作均会打印,请求输入学号的函数

void inputStudentNo(char s[], char no[]) {
	printf("请输入要%s的学生学号:", s);
	scanf("%s", no);
}

(这里专门编写这个函数可以简化后续的代码)

2)增加学生记录

bool addNode(Link head){
 Link node;
 node=(Link)malloc(sizeof(Node));
inputStudent(node);//给数据域填信息
 Link p,q;//用来查找插入数据点
 p=head;
 q=head->next;
 if(q==NULL)//如果还没有添加数据
 head->next=node;
 else{
    //循环访问链表中的所有节点
  while(q!=NULL){
   if (strcmp(node->data.studentNo, q->data.studentNo) < 0) {
       p->next=node;
       node->next=q;
       return true;
  }else{
       p=q;
       q=q->next;
   }
  }
//如果没能提前退出循环,则说明之前没有插入,那么当前node节点的学号是最大值,此时插在链表的最后面
 q->next=node;
 }
 return true;
}

(这个是给每个链表数据域填信息的函数,重点是将每个结点的next域都先赋为NULL )

void inputStudent(Link l) {
	printf("请输入学生学号:");
	scanf("%s", l->data.studentNo);
	printf("请输入学生的姓名:");
	scanf("%s", l->data.studentName);
    printf("请输入学生的性别:");
    scanf("%s", l->data.studentgender);
    printf("请输入学生的政治面貌:");
    scanf("%s", l->data.studentleague);

	//每个新创建的节点的next域都初始化为NULL
	l->next = NULL;
}

 3)删除学生记录

bool deleteNode(Link head) {
	// 按照给定的学号删除学生记录,如果删除成功返回true,如果没找到学号返回false
	//输入要处理的学号
	char no[NO_LENGTH];
	inputStudentNo("删除", no);
	if (head == NULL || head->next == NULL)
		return false;
	Link p, q;
	p = head;
	q = head->next;
	while (q != NULL) {
		if (strcmp(q->data.studentNo, no) == 0) {
			p->next = q->next;
			free(q);
			return true;
		} else {
			p = q;
			q = q->next;
		}
	}
	return false;
}

3)查找学生记录  

bool queryNode(Link head) {
	// 按照给定的学号查询学生记录,如果查找成功返回true,如果没找到学号返回false
	//输入要处理的学号
	char no[NO_LENGTH];
	inputStudentNo("查询", no);
	if (head == NULL || head->next == NULL)
		return false;
	Link p;
	p = head->next;
	while (p != NULL) {
		if (strcmp(p->data.studentNo, no) == 0)
			return true;
		else
			p = p->next;
	}

	return false;
}

4)修改学生记录

bool modifyNode(Link head) {
	// 按照给定的学号找到学生记录节点,如果修改成功返回true,如果没找到学号返回false
	//输入要处理的学号
	char no[NO_LENGTH];
	inputStudentNo("修改", no);
	if (head == NULL || head->next == NULL)
		return false;
	char resetno[NO_LENGTH];
	char resetname[NAME_LENGTH];
	char resetgender[GENDER_LENGTH];
	char resetleague[LEAGUE_LENGTH];
	Link p = head->next;
	while (p != NULL) {
		if (strcmp(p->data.studentNo, no) == 0) {
			printf("请输入您要修改的信息类型:\n");
			char type[20];
			scanf("%s", type);
			if (strcmp(type, "姓名") == 0) {
				printf("请输入修改后的姓名:\n");
				scanf("%s", resetname);
				strcpy(p->data.studentName, resetname);
				return true;
			} else if (strcmp(type, "学号") == 0) {
				printf("请输入修改后的学号:\n");
				scanf("%s", resetno);
				strcpy(p->data.studentNo, resetno);
				return true;
			}
			else if (strcmp(type, "性别") == 0) {
				printf("请输入修改后的性别:\n");
				scanf("%s", resetgender);
				strcpy(p->data.studentgender, resetgender);
				return true;
			}
			else if (strcmp(type, "政治面貌") == 0) {
				printf("请输入修改后的政治面貌:\n");
			    scanf("%s", resetleague);
				strcpy(p->data.studentleague, resetleague);
				return true;

			}
		} else {
			p = p->next;
		}
	}
	return false;
}

5)统计学生人数

int countNode(Link head) {
	//统计学生人数,扫描链表统计节点个数,返回节点数
	Link p;
	int count = 0;
	p = head->next;
	while (p != NULL) {
		count++;
		p = p->next;
	}
	return count;
	//填充代码
}

6)显示学生信息

void displayNode(Link head) {
	// 填写代码,根据传入的链表head头指针,扫描链表显示所有节点的信息
	Link p = head->next;
	while (p != NULL) {
		printf("%s %s %s %s\n", p->data.studentName, p->data.studentNo,p->data.studentgender,p->data.studentleague);
		p = p->next;
	}
}

7)退出系统

void clearLink(Link head) {
	Link q, p;
	//遍历链表,用free语句删除链表中用malloc建立起的所有的节点
	while (head->next != NULL) {
		p = head;
		head = head->next;
		free(p);
	}
}

四,完整代码

这里参考了《懒猫老师-C语言-链表作业1:学生管理系统》实验的题目模板~有错误欢迎指正呀~

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdbool.h>

#define NO_LENGTH  20
#define NAME_LENGTH 11
#define GENDER_LENGTH 11
#define LEAGUE_LENGTH 11

/* 定义学生结构体的数据结构 */
typedef struct Student {
	char studentName[NAME_LENGTH];//姓名
	char studentNo[NO_LENGTH];//学号
	char studentgender[GENDER_LENGTH];//性别
	char studentleague[LEAGUE_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);
	printf("请输入学生的性别:");
	scanf("%s", l->data.studentgender);
	printf("请输入学生的政治面貌:");
	scanf("%s", l->data.studentleague);

	//每个新创建的节点的next域都初始化为NULL
	l->next = NULL;
}

void inputStudentNo(char s[], char no[]) {
	printf("请输入要%s的学生学号:", s);
	scanf("%s", no);
}

void displayNode(Link head) {
	// 填写代码,根据传入的链表head头指针,扫描链表显示所有节点的信息
	Link p = head->next;
	while (p != NULL) {
		printf("%s %s %s %s\n", p->data.studentName, p->data.studentNo, p->data.studentgender, p->data.studentleague);
		p = p->next;
	}
}

/* 增加学生记录 */
bool addNode(Link head) {
	Link p, q;  //p,q两个节点一前一后
	Link node;  //node指针指向新创建的节点
	node = (Link)malloc(sizeof(Node));
	inputStudent(node);

	q = head;
	p = head->next;  //q指向head后面的第一个有效节点
	if (head->next == NULL)
		//链表为空时
		head->next = node;
	else {
		//循环访问链表中的所有节点
		while (p != NULL) {
			if (strcmp(node->data.studentNo, p->data.studentNo) < 0) {
				//如果node节点的学号比p节点的学号小,则插在p的前面,完成插入后,提前退出子程序
				q->next = node;
				node->next = p;
				return true;
			} else {
				//如果node节点的学号比p节点的学号大,继续向后移动指针(依然保持pq一前一后)
				q = p;
				p = p->next;

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

	}
	return true;
}

bool deleteNode(Link head) {
	// 按照给定的学号删除学生记录,如果删除成功返回true,如果没找到学号返回false
	//输入要处理的学号
	char no[NO_LENGTH];
	inputStudentNo("删除", no);
	if (head == NULL || head->next == NULL)
		return false;
	Link p, q;
	p = head;
	q = head->next;
	while (q != NULL) {
		if (strcmp(q->data.studentNo, no) == 0) {
			p->next = q->next;
			free(q);
			return true;
		} else {
			p = q;
			q = q->next;
		}
	}
	return false;
}

bool queryNode(Link head) {
	// 按照给定的学号查询学生记录,如果查找成功返回true,如果没找到学号返回false
	//输入要处理的学号
	char no[NO_LENGTH];
	inputStudentNo("查询", no);
	if (head == NULL || head->next == NULL)
		return false;
	Link p;
	p = head->next;
	while (p != NULL) {
		if (strcmp(p->data.studentNo, no) == 0)
			return true;
		else
			p = p->next;
	}

	return false;
}

bool modifyNode(Link head) {
	// 按照给定的学号找到学生记录节点,如果修改成功返回true,如果没找到学号返回false
	//输入要处理的学号
	char no[NO_LENGTH];
	inputStudentNo("修改", no);
	if (head == NULL || head->next == NULL)
		return false;
	char resetno[NO_LENGTH];
	char resetname[NAME_LENGTH];
	char resetgender[GENDER_LENGTH];
	char resetleague[LEAGUE_LENGTH];
	Link p = head->next;
	while (p != NULL) {
		if (strcmp(p->data.studentNo, no) == 0) {
			printf("请输入您要修改的信息类型:\n");
			char type[20];
			scanf("%s", type);
			if (strcmp(type, "姓名") == 0) {
				printf("请输入修改后的姓名:\n");
				scanf("%s", resetname);
				strcpy(p->data.studentName, resetname);
				return true;
			} else if (strcmp(type, "学号") == 0) {
				printf("请输入修改后的学号:\n");
				scanf("%s", resetno);
				strcpy(p->data.studentNo, resetno);
				return true;
			} else if (strcmp(type, "性别") == 0) {
				printf("请输入修改后的性别:\n");
				scanf("%s", resetgender);
				strcpy(p->data.studentgender, resetgender);
				return true;
			} else if (strcmp(type, "政治面貌") == 0) {
				printf("请输入修改后的政治面貌:\n");
				scanf("%s", resetleague);
				strcpy(p->data.studentleague, resetleague);
				return true;

			}
		} else {
			p = p->next;
		}
	}
	return false;
}

int countNode(Link head) {
	//统计学生人数,扫描链表统计节点个数,返回节点数
	Link p;
	int count = 0;
	p = head->next;
	while (p != NULL) {
		count++;
		p = p->next;
	}
	return count;
	//填充代码
}

void clearLink(Link head) {
	Link q, p;
	//遍历链表,用free语句删除链表中用malloc建立起的所有的节点
	while (head->next != NULL) {
		p = head;
		head = head->next;
		free(p);
	}
}

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
发出的红包

打赏作者

想写好代码的小猫头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值