一个简易版的学生信息管理系统,主要是为了练习链表。这里排序是直接交换了节点,类似冒泡排序法

student.c

#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "student.h"
void makeMenu() // 制作菜单
{
    // 排序+文件
    printf("---------【链式学生管理系统】---------\n");
    printf("\t\t0.退出功能\n");
    printf("\t\t1.录入功能\n");
    printf("\t\t2.浏览功能\n");
    printf("\t\t3.查找功能\n");
    printf("\t\t4.修改功能\n");
    printf("\t\t5.删除功能\n");
    printf("\t\t6.按照分数进行排序\n");
    printf("\t\t7.保存到文件\n");
    printf("-------------------------------------\n");
    printf("请输入(0~7):");
}
// 根据分数排序
void sort_sorce(Node *headnode)
{
    Node *temp;
    Node *e_pre = headnode;         // 外层前一个节点
    Node *e_index = headnode->next; // 外层当前节点
    Node *pre = headnode;           // 前一个节点
    Node *index = headnode->next;   // 当前节点
    if (e_index == NULL)
    {
        printf("没有数据\n");
        return;
    }
    while (e_index->next) // 预防野指针
    {
        while (index)
        {
            if (e_index->data.sorce > index->data.sorce) // 如果前面的大于后面的
            {
                if (e_index != pre)
                {
                    detelt_node(list, index); // 删除当前节点
                    detelt_node(list, e_index);
                    index->next = e_pre->next; // 内层这个跑到外层
                    e_pre->next = index;

                    e_index->next = pre->next; // 外层跑到内层
                    pre->next = e_index;
                }
                else if (e_index == pre) // 挨边两个进行交换了
                {
                    detelt_node(list, index);
                    index->next = e_pre->next;
                    e_pre->next = index;
                    pre = index;
                }
                temp = e_index; // 两个指针进行交换
                e_index = index;
                index = temp;
            }
            pre = pre->next;
            index = index->next;
        }
        e_index = e_index->next; // 更新外层指针指向节点
        e_pre = e_pre->next;
        index = e_index->next; // 更新内层指针指向的节点
        pre = e_index;
    }
}
// 删除指定节点
void detelt_node(Node *headnode, Node *dest)
{

    Node *pre = headnode;       // 头节点
    Node *cur = headnode->next; // 第一个节点
    while ((cur != NULL) && cur != dest)
    {
        pre = cur;
        cur = cur->next;
    }
    if (cur != NULL)
    {
        Node *node = cur;
        pre->next = cur->next;
    }
    else
        printf("删除失败,没有目标节点\n");
}
// 创建节点
Node *creatNode(struct student data)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    assert(newNode);
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}
// 创建头节点
Node *creatHead()
{
    Node *headHead = (Node *)malloc(sizeof(Node));
    assert(headHead);
    headHead->next = NULL;
    return headHead;
}
// 插入节点 头插法
void insertData(Node *headnode, struct student stu)
{
    Node *newData = creatNode(stu);
    newData->next = headnode->next;
    headnode->next = newData;
}
// 根据名字删除节点
void detelenode(Node *headnode, const char *name)
{
    Node *pre = headnode;       // 头节点
    Node *cur = headnode->next; // 第一个节点
    while ((cur != NULL) && (strcmp(cur->data.name, name)))
    {
        pre = cur;
        cur = cur->next;
    }
    if (cur != NULL)
    {
        Node *node = cur;
        pre->next = cur->next;
        free(node);
    }
    else
        printf("删除失败,没有找到数据\n");
}
// 查询
Node *searchByName(Node *headnode, const char *name)
{
    Node *searchnode = headnode;
    while (searchnode != NULL && (strcmp(searchnode->data.name, name)))
    {
        searchnode = searchnode->next;
    }
    if (searchnode != NULL)
    {
        return searchnode;
    }
    else
        printf("查询错误,没有该信息");
    return NULL;
}
// 打印节点
void printList(Node *headnode)
{
    Node *pmove = headnode->next; // 第一个节点
    printf("姓名\t分数\t年龄\n");
    while (pmove != NULL)
    {
        printf("%s\t%d\t%d\n", pmove->data.name,
               pmove->data.sorce, pmove->data.age);
        pmove = pmove->next;
    }
}
// 修改节点
void update_node(Node *headnode, const char *name)
{
    struct student stu;
    Node *node = searchByName(headnode, name);
    if (node)
    {
        printf("请重新输入学生的信息:\n");
        printf("name:\n");
        scanf("%s", stu.name);
        printf("sorce:\n");
        scanf("%d", &stu.sorce);
        printf("age:\n");
        scanf("%d", &stu.age);
        memcpy(&node->data, &stu, sizeof(stu));
    }
    else
        printf("不存在该学生信息\n");
}
// 保存到文件
void saveToFile(Node *headnode, const char *fileName)
{
    Node *index = headnode->next;
    FILE *fp = fopen(fileName, "w");
    if (fp == NULL)
    {
        printf("打开失败\n");
        return;
    }
    while (index)
    {
        fprintf(fp, "%s\t%d\t%d\n", index->data.name,
                index->data.sorce, index->data.age);
        index = index->next;
    }
    printf("保存成功\n");
    fclose(fp);
}
void readFromFile(Node *headNode, const char *fileName)
{
    stu student;
    FILE *fp = fopen(fileName, "r");
    if (fp == NULL)
    {
        printf("打开失败\n");
        return;
    }
    while (fscanf(fp, "%s\t%d\t%d\n", student.name, &student.sorce, &student.age) != EOF)
    {
        insertData(headNode, student);
    }
    fclose(fp);
}
void keyDown()
{
    int key;
    struct student stu;
    char *name;
    scanf("%d", &key);
    switch (key)
    {
    case 0:
        printf("退出模块....\n");
        system("pause");
        exit(0);
        break;
    case 1:
        printf("录入信息...\n");
        printf("请输入学生信息(name,sorce,age)\n");
        scanf("%s%d%d", stu.name, &stu.sorce, &stu.age);
        insertData(list, stu);
        break;
    case 2:
        printf("----【浏览功能】----\n");
        printList(list);
        break;
    case 3:
        printf("请输入要查询的学生姓名:\n");
        scanf("%s", name);
        printf("name:%s sorce:%d age:%d\n", searchByName(list, name)->data.name,
               searchByName(list, name)->data.sorce, searchByName(list, name)->data.age);
        break;
    case 4:
        printf("请输入要修改的学生姓名:\n");
        scanf("%s", name);
        update_node(list, name);
        break;
    case 5:
        printf("请输入要删除的学生姓名:\n");
        scanf("%s", name);
        detelenode(list, name);
        break;
    case 6:
        sort_sorce(list);
        break;
    case 7:
        saveToFile(list, "student.txt");
        break;
    default:
        break;
    }
}
int main()
{
    list = creatHead();
    stu init1[5] = {
        {"ta1", 30, 10},
        {"ta4", 50, 10},
        {"ta2", 10, 10},
        {"ta5", 40, 10},
        {"hah", 9, 10},
    };
    for (int i = 0; i < 5; i++)
    {
        insertData(list, init1[i]);
    }

    while (1)
    {

        makeMenu();
        keyDown();
    }
}

student.h

#ifndef _STUDENT_H
#define _STUDENT_H
typedef struct student
{
    char name[20];
    char sorce;
    char age;
} stu;
typedef struct Node
{
    struct student data;
    struct Node *next;
} Node;
Node *list;
// 创建节点
Node *creatNode(struct student data);
// 创建头节点
Node *creatHead();
// 插入节点 头插法
void insertData(Node *headnode, struct student stu);
// 根据名字删除节点
void detelenode(Node *headnode, const char *name);
// 查询
Node *searchByName(Node *headnode, const char *name);
// 打印
void printList(Node *headnode);
// 按键输入
void keyDown();
void makeMenu(); // 制作菜单
// 根据分数排序
void sort_sorce(Node *headnode);
// 删除指定节点
void detelt_node(Node *headnode, Node *dest);
// 修改节点
void update_node(Node *headnode, const char *name);
#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值