带头结点单链表插入,删除,查找与排序实现一个简单的基于链表结构的学生管理系统

发布时间 2023-06-29 17:30:54作者: 大海&

链表结构和操作方法

//
// 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