带头结点单链表插入,删除,查找与排序实现一个简单的基于链表结构的学生管理系统
链表结构和操作方法
//
// Created by Administrator on 2023/6/12.
//
#ifndef CODE_LINKEDLIST_H
#define CODE_LINKEDLIST_H
#include <iostream>
#include <cstring>
#include <stdlib.h>
#include "student.h"
typedef struct link_list {
// 方便存放任意类型的数据
void *data;
struct link_list *next;
} link_list;
/**
* 链表初始化
* @return
*/
link_list *init_link_list();
/**
* 链表尾部添加
* @param head
* @param data
*/
void push(link_list *head, void *data);
/**
* 遍历链表
* @param head
* @param call_back
*/
void link_list_each(link_list *head, void (*call_back)(void *));
/**
* 查找数据返回数据链表
* @param head 需要查找的链表
* @param find_list 返回最后一个找到的节点
* @param call_back 根据传入的回调函数查找对应的数据
* @param parameter 查找的数据
* @return
*/
link_list *find(link_list *head, link_list *find_list, int (*call_back)(void *, void *), void *parameter);
/**
* 删除结点
* @param head
* @param call_back
* @param parameter
*/
int deleted(link_list *head, int (*call_back)(void *, void *), void *parameter);
/**
* 冒泡排序
* @param head
* @param call_back 回调函数需要返回排序的内容
*/
void sort(link_list *head, char *(*call_back)(void *));
/**
* 链表初始化
* @return
*/
link_list *init_link_list() {
link_list *head;
head = (link_list *) malloc(sizeof(link_list));
head->next = NULL;
head->data = NULL;
return head;
}
/**
* 链表尾部添加
* @param head
* @param data
*/
void push(link_list *head, void *data) {
link_list *p = head;
while (p->next) {
p = p->next;
}
link_list *q = init_link_list();
q->data = data;
q->next = NULL;
p->next = q;
}
/**
* 遍历链表
* @param head 链表
*/
void link_list_each(link_list *head, void (*call_back)(void *)) {
if (!head) return;
link_list *node = head;
while (node) {
if (node->data)
call_back(node->data);
node = node->next;
}
}
/**
* 查找数据返回数据链表
* @param head 需要查找的链表
* @param find_list 返回最后一个找到的节点
* @param call_back 根据传入的回调函数查找对应的数据
* @param parameter 查找的数据
* @return
*/
link_list *find(link_list *head, link_list *find_list, int (*call_back)(void *, void *), void *parameter) {
link_list *p = head->next;
link_list *find_data = init_link_list();
static int i = 0;
while (p) {
if (call_back(p->data, parameter)) {
// 支持返回多个相同的数据
push(find_data, p->data);
if (find_list)
find_list->next = p;
}
p = p->next;
}
i = 0;
if (find_data->next)
return find_data;
else return NULL;
}
/**
* 删除结点
* @param head
* @param call_back
* @param parameter
*/
int deleted(link_list *head, int (*call_back)(void *, void *), void *parameter) {
link_list *p = head;
link_list *q = p;
while (p) {
if (p->data && call_back(p->data, parameter)) {
q->next = p->next;
free(p);
return 1;
}
q = p;
p = p->next;
}
return -1;
}
/**
* 冒泡排序
* @param head
* @param call_back 回调函数需要返回排序的内容
*/
void sort(link_list *head, char *(*call_back)(void *)) {
link_list *node = head->next;
link_list *node_next;
void *temp;
while (node) {
for (node_next = node->next; node_next; node_next = node_next->next) {
if (strcmp(call_back(node->data), call_back(node_next->data)) == 1) {
temp = node_next->data;
node_next->data = node->data;
node->data = temp;
}
}
node = node->next;
}
}
#endif //CODE_LINKEDLIST_H
学生数据结构和操作方法
//
// Created by Administrator on 2023/6/12.
//
#ifndef CODE_STUDENT_H
#define CODE_STUDENT_H
#include <string>
#include <cstring>
#include <conio.h>
#include "linked_list.h"
using namespace std;
typedef struct student {
char sno[10];
char name[20];
char gender[3];
// 2023-06-12
char birthday[11];
char addr[50];
char phone[12];
char email[30];
// 成绩
void *course;
} student;
/**
* 初始化
* @return
*/
student *init_student();
/**
* 根据学号对比学生
* @param data
* @param parameter
* @return
*/
int get_student_by_sno(void *data, void *parameter);
/**
* 根据姓名对比学生
* @param data
* @param parameter
* @return
*/
int get_student_by_name(void *data, void *parameter);
/**
* 根据姓名或者学号对比
* @param data
* @param parameter
* @return
*/
int get_student_by_sno_or_name(void *data, void *parameter);
/**
* 打印学生信息
* @param data
*/
void display_student(void *data);
/**
* 添加学生信息
* @return
*/
student *add_student();
/**
* 更新录入
* @param sno
* @return
*/
student *update_student(char *sno);
/**
* 快速添加学生消息
* @return
*/
student *add_student_fast();
/**
* 根据接收的数据返回学号sno
* @param data
* @return
*/
char *get_student_sno(void *data);
///////////////////////////////////////////////
/**
* 初始化
* @return
*/
student *init_student() {
return (student *) malloc(sizeof(student));
}
/**
* 根据学号对比学生
* @param data
* @param parameter
* @return
*/
int get_student_by_sno(void *data, void *parameter) {
student *stu = (student *) data;
if (!strcmp(stu->sno, (char *) parameter)) {
// cout << "查询" << "学号:" << stu->sno << "\t" << "查询参数:" << (char *) parameter << "\t" << "对比结果" << !strcmp(stu->sno, (char *) parameter) << endl;
return 1;
}
return 0;
}
/**
* 根据姓名对比学生
* @param data
* @param parameter
* @return
*/
int get_student_by_name(void *data, void *parameter) {
student *stu = (student *) data;
if (!strcmp(stu->name, (char *) parameter)) {
return 1;
}
return 0;
}
/**
* 根据姓名或者学号对比 支持模糊查找
* @param data
* @param parameter
* @return
*/
int get_student_by_sno_or_name(void *data, void *parameter) {
student *stu = (student *) data;
// cout << stu->sno << ":" << (char *)parameter << ":" << !(strcmp(stu->sno, (char *) parameter) || !strcmp(stu->name, (char *)parameter)) << endl ;
if (strstr(stu->sno, (char *) parameter) || strstr(stu->name, (char *)parameter)) {
return 1;
}
return 0;
}
/**
* 打印学生信息
* @param data
*/
void display_student(void *data) {
student *stu = (student *) data;
cout << "----------------------------------------------------------------------------------------------------------"
"-------------------------------------------------" << endl;
cout << setiosflags(ios::left)
<< "|学号:" << setw(10) << stu->sno
<< "|姓名:" << setw(10) << stu->name
<< "|性别:" << setw(3) << stu->gender
<< "|邮箱:" << setw(20) << stu->email
<< "|电话号码:" << setw(15) << stu->phone
<< "|生日:" << setw(15) << stu->birthday
<< "|地址:" << setw(32) << stu->addr << "|"
<< endl;
cout << "----------------------------------------------------------------------------------------------------------"
"-------------------------------------------------" << endl;
return;
}
/**
* 添加学生信息
* @return
*/
student *add_student() {
student *stu = init_student();
cout << endl << "请输入学号:";
cin >> stu->sno;
cout << endl << "请输入姓名:";
cin >> stu->name;
cout << endl << "请输入性别:";
cin >> stu->gender;
cout << endl << "请输入邮箱:";
cin >> stu->email;
cout << endl << "请输入手机号:";
cin >> stu->phone;
cout << endl << "请输入生日:";
cin >> stu->birthday;
cout << endl << "请输入地址:";
cin >> stu->addr;
return stu;
}
/**
* 更新录入
* @param sno
* @return
*/
student *update_student(char *sno) {
student *stu = init_student();
strcpy(stu->sno, sno);
cout << endl << "请输入姓名:";
cin >> stu->name;
cout << endl << "请输入性别:";
cin >> stu->gender;
cout << endl << "请输入邮箱:";
cin >> stu->email;
cout << endl << "请输入手机号:";
cin >> stu->phone;
cout << endl << "请输入生日:";
cin >> stu->birthday;
cout << endl << "请输入地址:";
cin >> stu->addr;
return stu;
}
/**
* 快速添加学生消息
* @return
*/
student *add_student_fast() {
student *stu = init_student();
cin >> stu->sno;
cin >> stu->name;
cin >> stu->gender;
cin >> stu->email;
cin >> stu->phone;
cin >> stu->birthday;
cin >> stu->addr;
return stu;
}
/**
* 根据接收的数据返回学号sno
* @param data
* @return
*/
char *get_student_sno(void *data) {
student *stu = (student *)data;
return stu->sno;
}
/**
* 获取出生日期
* @param data
* @return
*/
char *get_student_birthday(void *data) {
student *stu = (student *)data;
return stu->birthday;
}
/**
* 输入密码
* @return
*/
char *input_password() {
char *password = (char *)malloc(sizeof(char)*10); //存储密码
int i = 0; //记录密码长度
char c; //用于实现密码隐式输入
while (1) {
c = getch(); //用 _getch() 函数输入,字符不会显示在屏幕上
if (c == '\r') { //遇到回车,表明密码输入结束
break; //while 循环的出口
}
else if (c == '\b') { //遇到退格,需要删除前一个星号
printf("\b \b"); //退格,打一个空格,再退格,实质上是用空格覆盖掉星号
--i;
}
else {
password[i++] = c;//将字符放入数组
printf("*");
}
}
password[i] = '\0';
return password;
}
#endif //CODE_STUDENT_H
应用
//
// Created by Administrator on 2023/6/12.
//
#ifndef STUDENTMANNAGESYSTEM_MENU_H
#define STUDENTMANNAGESYSTEM_MENU_H
#include <iostream>
#include "student.h"
#include "file_util.h"
using namespace std;
void menu(link_list *list) {
cout << "=========================学生管理系统=======================" << endl;
cout << "\t\t\t 1.添加学生消息" << endl;
cout << "\t\t\t 2.删除学生信息" << endl;
cout << "\t\t\t 3.修改学生信息" << endl;
cout << "\t\t\t 4.查询学生信息" << endl;
cout << "\t\t\t 5.查询所有学生信息" << endl;
cout << "\t\t\t 6.快速录入学生信息" << endl;
cout << "\t\t\t 7.清空文件" << endl;
cout << "\t\t\t 8.学生排序" << endl;
cout << "\t\t\t 9.存档" << endl;
cout << "\t\t\t 0.退出系统" << endl;
cout << "===========================================================" << endl;
int input;
cin >> input;
system("cls");
char temp_input[50];
link_list *link;
switch (input) {
case 1:
student *add;
add = add_student();
{
link = find(list, NULL, get_student_by_sno, (char *) add->sno);
if (link) {
cout << "已存在该用户" << endl;
cout << "该学生的信息如下:" << endl;
link_list_each(link, display_student);
} else {
push(list, add);
break;
}
}
break;
case 2:
cout << "请输入要删除学生的学号0R姓名:";
cin >> temp_input;
{
link = find(list, NULL, get_student_by_sno_or_name, (char *) temp_input);
if (link) {
cout << "该学生的信息如下:" << endl;
link_list_each(link, display_student);
} else {
cout << endl << "======================找不到此人==================" << endl;
break;
}
}
cout << "确认需要删除学生的学号:";
cin >> temp_input;
int d;
d = deleted(list, get_student_by_sno, (void *) temp_input);
if (d == 1) {
cout << endl << "======================删除成功==================" << endl;
} else {
cout << endl << "======================找不到此人==================" << endl;
}
break;
case 3:
cout << "请输入要修改学生的学号OR姓名:";
cin >> temp_input;
{
link = find(list, NULL, get_student_by_sno_or_name, (char *) temp_input);
if (link) {
cout << "该学生的信息如下:" << endl;
link_list_each(link, display_student);
} else {
cout << endl << "======================找不到此人==================" << endl;
break;
}
}
cout << "确认需要修改的学号:";
link_list *find_node;
cin >> temp_input;
find_node = init_link_list();
link = find(list, find_node, get_student_by_sno, (char *) temp_input);
// 指针深拷贝
// memcpy(find_node, list, sizeof(link_list));
link_list_each(link, display_student);
if (find_node->next) {
// 更新数据
find_node->next->data = update_student(temp_input);
} else {
cout << endl << "======================找不到此人==================" << endl;
}
break;
case 4:
cout << "请输入要查询学生的学号OR姓名:";
cin >> temp_input;
link = find(list, NULL, get_student_by_sno_or_name, (char *) temp_input);
if (link) {
cout << "该学生的信息如下:" << endl;
link_list_each(link, display_student);
} else {
cout << endl << "======================找不到此人==================" << endl;
}
break;
case 5:
system("cls");
cout << "||===============================================================学生表==================================="
"===============================================||" << endl;
link_list_each(list, display_student);
break;
case 6:
cout << "请输入:";
student *fast_add;
add = add_student_fast();
{
link = find(list, NULL, get_student_by_sno, (char *) add->sno);
if (link) {
cout << "已存在该用户" << endl;
cout << "该学生的信息如下:" << endl;
link_list_each(link, display_student);
} else {
push(list, add);
break;
}
}
break;
case 7:
cout << "这是一个危险操作请输入密码:\a\a\a";
char *password;
password = input_password();
cout << endl;
if (!strcmp(password, "password")) {
clear_file();
list->next = NULL;
} else {
cout << endl << "密码不正确!" << endl;
}
break;
case 8:
cout << "===========排序============" << endl;
cout << "\t" << "1.学号排序" << endl;
cout << "\t" << "2.年龄排序" << endl;
cout << "==========================" << endl;
int sort_in;
cin >> sort_in;
if (sort_in == 1) {
sort(list, get_student_sno);
} else if (sort_in == 2) {
sort(list, get_student_birthday);
}
cout << "排序完成" << endl;
link_list_each(list, display_student);
break;
case 9:
::system("cls");
cout << endl << "=========================保存中。。。。。。。。。。";
file_write(list);
cout << endl << "======================保存成功==================" << endl;
break;
case 0:
cout << "确认退出系统吗?没有存档会丢失数据哦!(y/n)" << endl;
char in;
cin >> in;
if (in == 'y' || in == 'Y') {
cout << "ヾ( ̄▽ ̄)Bye~Bye~";
system("pause");
exit(0);
}
break;
default:
cout << "非法操作请重试!" << endl;
}
}
#endif //STUDENTMANNAGESYSTEM_MENU_H
本文作者:大海&
本文链接:https://www.cnblogs.com/oceanus/p/17514752.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。