学生信息管理系统--动态链表

链表:由独立的节点组成(物理上不连续),各节点之间通过指针域连接,达到逻辑上的连续

节点由两部分组成:数据域、指针域

数据域:存放数据

指针域:保存下一个节点的地址编号

typedef struct stu
{
    /*既然是学生信息管理系统,首先来了解下学生有啥信息
    学生有学号、姓名、分数,还有年龄和性别等等,其他的就不搞了挺多的,基本都差不多*/

    // 数据域
    int num;       // num代表学生的学号
    char name[32]; // 字符数组name代表学生的姓名
    char sex[18];  // sex代表学生的性别
    int age;       // age表示学生的年龄
    float score;   // score代表学生的分数

    // 指针域
    struct stu *next; // 保存下一个节点的信息

} STU;

我写了一个单向的动态链表作为学生信息管理系统的技术支持

链表说白了,由若干个节点组成,每一个节点都是一个结构体(如上结构体STU代码)和结构体的每一个成员对应的数据,加在一块儿就成了一个链表节点信息。

废话不多说,上干货,瞧瞧我花了四个小时弄好的代码程序,哇哈哈哈!!!

先别急!!!

 我分了三个文件,见上图

这是main.c文件,系统调用主程序入口

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "link.h"

STU *head = NULL;
void help(void)
{
    printf("************************************************\n");
    printf("                 学生信息管理系统                   \n");
    printf("各个指令及其功能说明                                 \n");
    printf("1.help:         帮助信息                            \n");
    printf("2.quit:         退出进程                            \n");
    printf("3.insert:       插入链表节点                         \n");
    printf("4.printf:       遍历链表节点                         \n");
    printf("5.search:       查询链表节点                         \n");
    printf("6.delete:       删除链表节点                         \n");
    printf("7.free:         释放整个链表                         \n");
    printf("8.reverse:      链表的逆序                           \n");
    printf("9.sort:         链表的排序                           \n");
    printf("************************************************ \n");
}
int main(int argc, char const *argv[])
{
    printf("欢迎访问学生信息管理系统\n");
    printf("该系统提供了学生学号、姓名等相关信息存储和查询等功能,如需帮助请键入 “help” 指令\n");
    while (1)
    {
        char cmd[32] = "";
        printf("请输入操作指令:");
        scanf("%s", cmd);

        if (strcmp(cmd, "insert") == 0)
        {
            printf("请输入要插入的学生信息(学号、姓名、性别、年龄、分数): ");
            STU temp;
            scanf("%d %s %s %d %f", &temp.num, temp.name, temp.sex, &temp.age, &temp.score);

            // 将temp的数据插入到堆区链表中
            head = insert_link(head, temp); // 每次更新head的指向
        }
        else if (strcmp(cmd, "printf") == 0)
        {
            printf_link(head);
        }
        else if (strcmp(cmd, "search") == 0)
        {
            printf("该学生管理查询系统目前仅仅提供根据学号查询学生的相关信息\n");
            printf("如有需求,可自行完善\n");
            printf("****************************\n");
            printf("\n");
            printf("请输入要查询的学号:");
            int num = 0;
            scanf("%d", &num);
            STU *ret = serach_link(head, num);
            if (ret != NULL)
            {
                printf("查询结果:%d %s %s %d %f\n", ret->num, ret->name, ret->sex, ret->age, ret->score);
            }
        }
        else if (strcmp(cmd, "delete") == 0)
        {
            printf("该学生管理查询系统目前仅仅提供根据<<姓名>>删除学生的相关信息\n");
            printf("如有需求,可自行完善\n");
            printf("****************************\n");
            printf("\n");
            printf("请输入需要删除的姓名:");
            char name[32] = "";
            scanf("%s", name);
            head = delete_link(head, name);
        }
        else if (strcmp(cmd, "free") == 0)
        {
            printf("请稍后,正在清空链表信息......\n");
            sleep(1);
            head = free_link(head);
        }
        else if (strcmp(cmd, "reverse") == 0)
        {
            printf("正在逆序排序中,请稍后......\n");
            sleep(1);
            head = reverse_link(head);
        }
        else if (strcmp(cmd, "sort") == 0)
        {
            printf("正在按照从小到大的分数排序中,请稍后......\n");
            sleep(1);
            sort_link(head);
        }
        else if (strcmp(cmd, "help") == 0)
        {
            printf("欢迎您访问学生信息管理系统帮助手册\n");
            sleep(1);
            help();
        }
        else if (strcmp(cmd, "quit") == 0)
        {

            printf("请稍后,正在清空链表信息......\n");
            sleep(1);
            head = free_link(head);
            printf("学生信息管理系统已经退出\n");
            printf("欢迎下次光临\n");
            sleep(1);
            printf("再见!!!\n");
            break;
        }
        else
        {
            printf("输入的指令有误,请重新输入!");
        }
    }

    return 0;
}

这是link.h文件,是link.c文件的头文件

#ifndef __LINK_H__
#define __LINK_H__
typedef struct stu
{
    /*既然是学生信息管理系统,首先来了解下学生有啥信息
    学生有学号、姓名、分数,还有年龄和性别等等,其他的就不搞了挺多的,基本都差不多*/

    // 数据域
    int num;       // num代表学生的学号
    char name[32]; // 字符数组name代表学生的姓名
    char sex[18];  // sex代表学生的性别
    int age;       // age表示学生的年龄
    float score;   // score代表学生的分数

    // 指针域
    struct stu *next; // 保存下一个节点的信息

} STU;

extern STU *insert_link(STU *head, STU temp);
extern void printf_link(STU *head);             // 遍历链表信息
extern STU *serach_link(STU *head, int num);    // 按照学号查找链表信息
extern STU *delete_link(STU *head, char *name); // 根据姓名删除学生信息
extern STU *free_link(STU *head);               // 释放整个链表信息
extern STU *reverse_link(STU *head);            // 链表的逆序
extern void sort_link(STU *head);               // 按照学生的分数从小到大进行排序
#endif

这是link.c文件,功能的实现都在这儿,最最最重要的部分,哇哈哈哈!!!

#include "link.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// link单向动态链表提供了三种插入方式
/*第一种,是在head头部之前插入数据
第二种,是在link单向动态链表的尾部插入数据
第三种,是按照学生的学号从小到大有序插入*/
#if 0
//头部之前插入数据

STU *insert_link(STU *head,STU temp)
{
//1、先申请插入的节点p1堆区空间并将数据复制到该空间内
STU *p1=(STU *)calloc(1,sizeof(STU));
*p1=temp;
p1->next=NULL;

//2、判断链表是否存在
if(NULL==head)
{
    head=p1;
    return head;
}
else
{
    p1->netx=head;
    head=p1;
    return head;//及时更新头部信息
}
}
#endif

#if 0
//尾部插入数据
STU *insert_link(STU *head,STU temp)
{
    //1、先申请插入的节点p2堆区空间并将数据复制到该空间内
STU *p2=(STU *)calloc(1,sizeof(STU));
*p2=temp;
p2->next=NULL;

//2、判断链表是否存在
if(NULL==head)
{
    head=p2;
    return head;
}
else
{
    //3、寻找尾部节点
    STU *prev=head;
    while(prev->next!=NULL)
    {
        prev=prev->next;
    }
        //插入尾部节点
        prev->next=p2;
}
    return head;//及时更新头部信息
}
#endif

#if 1
// 按照学号有序插入
STU *insert_link(STU *head, STU temp)
{
    // 1、为插入的数据申请堆区空间并并将数据复制到堆区空间内
    STU *p3 = (STU *)calloc(1, sizeof(STU));
    *p3 = temp;
    p3->next = NULL;

    // 2、判断链表是否存在
    if (NULL == head)
    {
        head = p3;
        return head;
    }
    else
    {
        // 3、建立链表上一个节点和下一个节点指针,并建立关系
        STU *prev, *pnext;
        prev = pnext = head;

        while ((pnext->num < p3->num) && (pnext->next != NULL)) //
        {
            prev = pnext;
            pnext = pnext->next; // 让prev永远指向pnext的上一个节点
        }
        // 4、寻找插入点
        if (pnext->num > p3->num) // 前、中部插入
        {
            if (pnext == head) // 前部插入
            {
                p3->next = head;
                head = p3;
                return head;
            }
            else // 中间插入
            {
                prev->next = p3;
                p3->next = pnext;
            }
        }
        else // 尾部插入
        {
            pnext->next = p3;
        }
    }
    return head;
}

#endif

void printf_link(STU *head) // 遍历链表信息
{
    // 1、先判断链表是否存在
    if (NULL == head)
    {
        printf("The linked list does not exist\n");
        return;
    }

    STU *pnext = head;
    while (pnext != NULL)
    {
        printf("%d %s %s %d %f ", pnext->num, pnext->name, pnext->sex, pnext->age, pnext->score);
        // 将pnext移动到下一个节点继续遍历
        pnext = pnext->next;
        printf("\n");
    }
    printf("\n");
    return;
}

STU *serach_link(STU *head, int num) // 按照学号查找链表信息
{
    // 老规矩先判断链表是否存在
    if (NULL == head)
    {
        printf("The linked list does not exist\n");
        return NULL;
    }
    else
    {
        // 逐个节点查找学号
        STU *pnext = head;
        while ((pnext->num != num) && (pnext->next != NULL)) // while循环查找num
        {
            pnext = pnext->next;
        }
        // 找到该学号
        if (pnext->num == num)
        {
            return pnext;
        }
        else
        {
            printf("链表中不存在该学号信息\n");
        }
    }
    return NULL;
}

STU *delete_link(STU *head, char *name) // 根据姓名删除学生信息
{
    // 先判断链表是否存在
    if (NULL == head)
    {
        printf("The Linked list does not exit\n");
        return NULL;
    }
    else
    {
        // 先建立上一个节点和下一个节点的信息和关系
        STU *prev, *pnext;
        prev = pnext = head;
        while ((strcmp(pnext->name, name) != 0) && (pnext->next != NULL))
        {
            prev = pnext;
            pnext = pnext->next;
        }
        // 寻找要删除的节点
        if (strcmp(pnext->name, name) == 0)
        {

            // 判断节点是否是head
            if (pnext == head)
            {
                head = pnext->next;
                free(pnext); // 删除节点
                return head;
            }
            else
            {
                prev->next = pnext->next;
                free(pnext);
            }
            printf("姓名为%s的学生信息已经全部删除\n", name);
        }
        else
        {
            printf("没有找到要删除的学生\n");
        }
    }
    return head;
}

STU *free_link(STU *head) // 释放整个链表信息
{
    // 先判断链表是否存在
    if (NULL == head)
    {
        printf("The Linked list does not exit\n");
        return NULL;
    }
    else
    {
        // 逐个释放链表节点
        STU *pnext = head;
        while (pnext != NULL)
        {
            // 让head保存下一个节点的位置
            head = pnext->next;
            free(pnext);
            pnext = head; // 然后让pnext指向下一个节点
        }
        printf("链表信息已经清空!!!\n");
    }
    return head;
}

STU *reverse_link(STU *head) // 链表的逆序
{
    // 先判断链表是否存在
    if (NULL == head)
    {
        printf("The Linked list does not exit\n");
        return NULL;
    }
    else
    {
        STU *pnext, *phead;
        pnext = head->next; // 让pnext保存head的下一个节点
        head->next = NULL;
        while (pnext != NULL)
        {
            phead = pnext->next; // 让phead备份pnext的下一个节点信息
            pnext->next = head;  // 将pnext下一个节点变成了头
            head = pnext;        // 让pnext跑到head的位置
            pnext = phead;       // 然后将备份的pnext下一个节点信息放到pnext原来的位置
        }
        printf("整个链表逆序完成,请遍历查看\n");
    }
    return head;
}

void sort_link(STU *head) // 按照学生的分数从小到大进行排序
{
    // 先判断链表是否存在
    if (NULL == head)
    {
        printf("The Linked list does not exit\n");
        return;
    }
    else
    {
        STU *p_i = head;
        while (p_i->next != NULL)
        {
            STU *p_s = p_i;       // 让p_s保存head的头部信息
            STU *p_j = p_s->next; // 让p_j保存head的下一个信息
            while (p_j != NULL)
            {
                if (p_s->score > p_j->score)
                    p_s = p_j;
                p_j = p_j->next;
            }
            if (p_i != p_s) // 如果p_i和p_s两个指针指向不是同一个节点,也就是p_s指向变了
            {
                // 数据发生交换
                STU temp = *p_i;
                *p_i = *p_s;
                *p_s = temp;
                // 指针域也发生交换
                temp.next = p_i->next; // 让temp指针来临时保存p_i的指针
                p_i->next = p_s->next;
                p_s->next = temp.next;
            }
            p_i = p_i->next; // 继续循环遍历
        }
        printf("整个链表排序完成,请遍历查看\n");
    }
}

该项目实现了以链表存储学生的相关信息,提供插入、删除、查找、遍历和排序包括逆序等功能,

根据指令来调用相关的函数,实现对应功能。

上运行结果图

学生信息插入操作(五个信息啊,不能少不能多,想变化。。。。。。自己弄)

 

学生信息的查询和删除操作

 

学生信息的从小到大排序和逆序两个操作

 

学生信息清空和退出学生信息管理系统操作

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值