您的位置:首页 > 编程语言 > C语言/C++

懒猫老师-C语言-链表作业1:学生管理系统

2020-06-24 22:16 70 查看

文章目录

  • 3.代码实现
  • 本文提供测试数据视频链接哦~
    运行时请将数据粘贴到输入框中。

    • 由于自己才疏学浅,难免会有纰漏,假如你发现了有错误的地方,还望留言给我指出来,我会对其加以修正。
    • 如果你觉得文章还不错,你的转发、分享、赞赏、点赞、留言就是对我最大的鼓励。
    • 感谢您的阅读,十分欢迎并感谢您的关注哦~

    1.基本思路

    2.步骤详解

    2.1.插入

    2.2.删除

    2.3.修改与清除

    3.代码实现

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #define ID_LENGTH   30
    #define NAME_LENGTH 30
    
    /* 定义学生结构体的数据结构 */
    typedef struct student
    {
    char studentId[ID_LENGTH];      // 学号
    char studentName[NAME_LENGTH];  // 姓名
    } STU;
    
    /* 定义每条记录或节点的数据结构 */
    typedef struct node
    {
    struct student data; //数据域
    struct node *next;   //指针域
    } Node, *Link;           //Node为node类型的别名, Link为node类型的指针别名
    
    void myMenu();                             // 提示菜单
    void inputStudent(Link newNode);           // 输入学生信息
    bool addNode(Link head);                   // 1.新增学生记录
    bool deleteNode(Link head);                // 2.删除学生记录
    bool queryNode(Link head);                 // 3.查找学生记录
    bool modifyNode(Link head);                // 4.1修改学生记录
    bool insertNode(Link head, Link newNode);  // 4.2插入一个学生记录
    int  countNode(Link head);                 // 5.统计学生人数
    void displayNode(Link head);               // 6.打印链表
    void destroyList(Link head);               // 7.销毁链表
    
    /* 定义提示菜单 */
    void myMenu()
    {
    printf("----------------------菜  单--------------------\n");
    printf("     1 增加学生记录            2 删除学生记录   \n");
    printf("     3 查找学生记录            4 修改学生记录   \n");
    printf("     5 统计学生人数            6 显示学生记录   \n");
    printf("     7 退出系统                                 \n");
    printf("------------------------------------------------\n");
    }
    
    /* 输入学生信息 */
    void inputStudent(Link newNode)
    {
    printf("请输入学生学号: ");
    scanf("%s", newNode->data.studentId);
    printf("请输入学生的姓名: ");
    scanf("%s", newNode->data.studentName);
    
    // 每个新创建的节点的next域都初始化为NULL
    newNode->next = NULL;
    }
    
    /* 1.增加学生记录 (按学号升序排序) */
    bool addNode(Link head)
    {
    Link node = (Link)malloc(sizeof(Node));
    inputStudent(node);
    
    /* 指针p, q的初始化, p前q后 */
    Link p = head;
    Link q = head->next;
    
    bool flag = false; // 是否增加成功
    
    if (head->next == NULL)
    {
    head->next = node;
    flag = true;
    }
    else
    {
    /* 循环访问链表中的所有节点 */
    while (q != NULL)
    {
    if (strcmp(node->data.studentId, q->data.studentId) > 0)
    {
    // 如果node节点的学号比q节点的学号大,继续向后移动指针(依然保持p前q后)
    p = q;
    q = q->next;
    }
    else
    {
    // 如果node节点的学号比q节点的学号小,则插在q的前面,完成插入后,提前退出子程序
    p->next = node;
    node->next = q;
    flag = true;
    break;
    }
    }
    }
    
    // 如果没能提前退出循环,则说明之前没有插入,那么当前node节点的学号是最大值,此时插在链表的最后面
    if (q == NULL && flag == false)
    {
    p->next = node;
    flag = true;
    }
    
    return flag;
    }
    
    /* 2.按照给定的学号删除学生记录,如果删除成功返回true,如果没找到学号返回false */
    bool deleteNode(Link head)
    {
    char deleteID[ID_LENGTH];
    printf("请输入要删除的学生学号:");
    scanf("%s", deleteID);
    
    // 1.指针p, q初始化
    Link p = head;
    Link q = head->next;
    
    // 2.查找该学号
    while (q)
    {
    if (strcmp(q->data.studentId, deleteID) == 0) // 查找成功!
    {
    p->next = q->next;
    free(q);
    return true;
    }
    else
    {
    p = q;
    q = q->next;
    }
    }
    
    return false;
    }
    
    /* 3.按照学号查询学生记录,如果查找成功返回true,如果没找到学号返回false */
    bool queryNode(Link head)
    {
    char queryID[ID_LENGTH];
    printf("请输入要查询的学生学号:");
    scanf("%s", queryID);
    
    Link p = head->next;
    
    while (p)
    {
    if (strcmp(p->data.studentId, queryID) == 0)
    {
    printf("%s的姓名是%s\n", queryID, p->data.studentName);
    return true;
    }
    else
    {
    p = p->next;
    }
    }
    
    return false;
    }
    
    /* 4.1 查找并修改学生记录,若成功返回true,否则返回false */
    bool modifyNode(Link head)
    {
    char newId[ID_LENGTH];        // 新学号
    char newName[NAME_LENGTH];    // 新名字
    
    char queryId[ID_LENGTH];
    printf("请输入要修改的学生的编号: ");
    scanf("%s", queryId);
    
    int select;
    printf("请输入要修改的项目: 1学号, 2姓名\n");
    scanf("%d", &select);
    
    if (select == 1)
    {
    Link p = head;
    Link q = head->next;
    
    while (q)
    {
    if (strcmp(q->data.studentId, queryId) == 0)
    {
    p->next = q->next;
    q->next = NULL;
    printf("请输入新学号: ");
    scanf("%s", newId);
    strcpy(q->data.studentId, newId);
    if (insertNode(head, q))
    {
    printf("修改成功了...");
    return true;
    }
    }
    else
    {
    p = q;
    q = q->next;
    }
    }
    }
    else if (select == 2)
    {
    Link p = head;
    while (p)
    {
    if (strcmp(p->data.studentId, queryId) == 0)
    {
    printf("请输入新名字: ");
    scanf("%s", newName);
    strcpy(p->data.studentName, newName);
    return true;
    }
    else
    {
    p = p->next;
    }
    }
    }
    else
    {
    printf("您的输入有误, 请重新输入。\n");
    return false;
    }
    }
    
    /* 4.2 插入一个学生记录 */
    bool insertNode(Link head, Link newNode)
    {
    Link p = head;
    Link q = head->next;
    
    if (head->next == NULL)
    {
    head->next = newNode;
    return true;
    }
    else
    {
    while (q != NULL)
    {
    if (strcmp(newNode->data.studentId, q->data.studentId) < 0)
    {
    p->next = newNode;
    newNode->next = q;
    return true;
    }
    else
    {
    p = q;
    q = q->next;
    }
    }
    }
    
    /*
    * 如果还没能退出循环,则说明之前没有插入,
    * 那么当前node节点的学号是最大值,此时插在链表的最后面
    */
    if (q == NULL)
    {
    p->next = newNode;
    return true;
    }
    
    return false;
    }
    
    /* 5.统计学生人数,扫描链表统计节点个数,返回节点数 */
    int countNode(Link head)
    {
    int count = 0;
    Link p = head->next;
    
    while (p)
    {
    count++;
    p = p->next;
    }
    
    return count;
    }
    
    /* 6.链表的输出: 根据传入的链表head头指针,扫描链表显示所有节点的信息 */
    void displayNode(Link head)
    {
    printf("\n\t      学生信息\n");
    printf("\t学号\t\t姓名    \n");
    
    Link p = head->next;
    while (p)
    {
    printf("\t%s\t\t%s\n", p->data.studentId, p->data.studentName);
    p = p->next;
    }
    }
    
    /* 7.销毁链表: 用free语句删除链表中用malloc建立起的所有的节点 */
    void destroyList(Link head)
    {
    Link p = head;
    Link q = head->next;
    
    while (q != NULL)
    {
    free(p);
    // 两个指针后移
    p = q;
    q = q->next;
    }
    
    free(p);
    head = NULL;
    
    printf("销毁成功!\n");
    }
    
    int main()
    {
    /*
    * 建立head头结点,在这个程序中head指向头结点,
    * 头结点data部分没有内容,其后续节点才有真正的数据
    */
    Link head = (Link)malloc(sizeof(Node));
    head->next = NULL;
    
    int count = 0; // 表示学生的人数 (case 5)
    int select;
    
    myMenu();
    
    while (true)
    {
    printf("\n\n------------------------------------------------");
    printf("\n请输入你的选择(1-7): ");
    scanf("%d", &select);
    
    switch (select)
    {
    case 1:                                  // 增加学生记录
    if (addNode(head))
    printf("成功增加一个学生记录。\n");
    break;
    case 2:                                  // 删除学生记录
    if (deleteNode(head))
    printf("成功删除一个学生记录。\n");
    else
    printf("没有找到要删除的学生节点。\n");
    break;
    case 3:                                  // 查询学生记录
    if (queryNode(head))
    printf("成功找到学生记录。\n");
    else
    printf("没有找到要查询的学生节点。\n");
    break;
    case 4:                                  // 修改学生记录
    if (modifyNode(head))
    printf("成功修改一个学生记录。\n");
    else
    printf("没有找到要修改的学生节点。\n");
    break;
    case 5:                                  // 统计学生人数
    count = countNode(head);
    printf("学生人数为:%d\n", count);
    break;
    case 6:                                  // 显示学生记录
    displayNode(head);
    break;
    case 7:                                  // 退出前清除链表中的所有结点
    destroyList(head);
    return 0;
    default:
    printf("输入不正确,应该输入1-7之间的数。\n");
    break;
    }
    }
    return 0;
    }
    /*测试数据:
    1
    101
    aaa
    1
    105
    bbb
    1
    103
    ccc
    1
    107
    ddd
    6
    2
    105
    6
    3
    101
    3
    999
    6
    4
    107
    1
    106
    6
    4
    101
    2
    AAA
    6
    5
    7
    */
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: