c语言数据结构实验:链表实现学生信息的储存

这篇具有很好参考价值的文章主要介绍了c语言数据结构实验:链表实现学生信息的储存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

首先感谢ChatGPT给我提供的帮助

进入正题
本文作者同为大一新生,写这篇文章的目的是记录自己的学习经历,以及帮助一些稍有困难的同学理解数据结构,能力有限,如有错误请指出。本文基于严蔚敏老师的《数据结构与算法(c语言版 第二版)》创作。(建议学习的时候搭配着书看)
学习前提
1.本文需要有一定的链表基础,如果对链表不太了解,建议对链表的结构稍加学习之后再来看
2.你需要明确知道实际参数和形式参数之间的关系如果不知道可以看作者的这篇文c语言实际参数与形式参数

实验内容是这样的

定义一个包含学生信息(学号,姓名,成绩)的链表,使其具有如下功能:
(1) 根据指定学生个数,逐个输入学生信息;
(2) 逐个显示学生表中所有学生的相关信息;
(3) 根据姓名进行查找,返回此学生的学号和成绩;
(4) 根据指定的位置可返回相应的学生信息(学号,姓名,成绩);
(5) 给定一个学生信息,插入到表中指定的位置;
(6) 删除指定位置的学生记录;

代码与讲解如下

头文件

首先你需要的头文件有

#include <stdio.h>	//这个不需要解释了吧~~~
#include <stdlib.h>	//因为我们需要malloc函数分配内存和free函数释放内存,至于这个头文件的具体内容,建议自己百度
#include <string.h>	//和字符串有关的函数

链表的定义

其次就是链表结点的定义(关于链表的基本构造,如果你不会的话,可以去看看青岛大学王卓老师的课程)
可能有些人会疑惑,这个typedef是什么东西,这里之后可能会出一篇文章详细介绍,你可以先简单把它理解为:可以为某一类型自定义名称。或者你自己抽个时间细细的查一查

typedef struct 
{
    char no[15];	//学号
    char name[8];	//名字
    int chengji;	//成绩
}student;			

typedef struct Lnode    
{
    student date;   //数据域	,这是结构体嵌套哦~~在这个结构体中嵌套了一个student的结构体
    struct Lnode *next;     //指针域
}Lnode,*linklist;   //指向节点的指针

输入

其次就是输入学生的信息函数了
我这里把初始化和输入写到了一起。因为在一次程序中,你输入只有一次执行,之后的添加都是插入

linklist scanflist() //输入学生信息(头插法)定义一个返回值是链表头指针的函数
{
	//创建一个链表头结点L,并将其next指针设置为NULL,从而创建一个空链表。
    linklist L;	
    L=(linklist)malloc(sizeof(Lnode));//书中用的是new,但那是c++语法,我们用malloc分配内存
    L->next=NULL;
    //定义一个结构体指针p,以及变量n存储学生数量,并读入n。     
    linklist p; int n,i;   
    printf("请输入输入的学生数量:");   
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        p=(linklist)malloc(sizeof(Lnode));  //通过调用 malloc() 函数为指针p分配内存空间,大小为结构体Lnode的大小。也就是创建一个新结点*P
        printf("请输入学生信息:\n");
        printf("学号:");
        scanf("%s",p->date.no);
        printf("姓名:");
        scanf("%s",p->date.name);	//这里你需要注意一下是字符串输入,前面不加取地址符
        printf("成绩:");
        scanf("%d",&(p->date.chengji));
        p->next=L->next;    //使p插入头结点后
        L->next=p;		
    }
   return L;    //返回链表的头指针 L。
}

打印

之后是打印学生信息的代码,注意这里的传参是指针,这里设计到实际参数和形式参数的知识可以看我之前写的文章文章传送点我

void printlist(linklist L)   //打印学生信息
{
    linklist n;	//定义一个指针n,初始化为链表头节点的下一个节点,也就是第一个实际存储学生信息的节点。

    n=L->next;
    while (n)//使用while循环遍历整个链表,当n指向的节点不为空时,执行下列操作
    {	//打印n指向的结点里的内容
        printf("学号:%s\n姓名:%s\n成绩:%d\n",n->date.no,n->date.name,n->date.chengji);	
        n=n->next;
        printf("\n");
    }
    printf("打印完成,谢谢使用\n");
    printf("————————————————————————————\n");  
}

插入

接下来就是插入程序代码
这里需要用户输入插入的结点位置,所以为了防止用户输入一个超出当前链表总长的结点。我们需要对链表长度进行测量并与输入的结点位置进行比对。
我们设置两个结构体类型指针p,s
然后我们让p指针指向第i-1给结点,然后再把s指向的结点接在后面。之后再调整结点中的指针域使其连结起来。

void charulist(linklist L)		
{
    int i,j,n;
    linklist s,p;		//定义结构体指针p和s
    p=L;
    while (p!=NULL) 	//测量一下现在链表的长度
    {					//除非p为空while循环继续
        p=p->next;		//p指向下一个结点
        n++;			//n加1
    }
    printf("请输入插入的结点的位置");
    scanf("%d",&i);
    while (i>n)
    {
        printf("输入的结点超过总长,请重新输入");
        scanf("%d",&i);
    }
    p=L;j=1;
    while (p&&(j<i))    //让p指向第i-1个结点
    {       
        p=p->next;
        ++j;
    }
    s=(linklist)malloc(sizeof(Lnode));  //用s指向准备插入的结点,并给它分配一个内存空间
    printf("请输入学生信息:\n");	//后面的内容和输入同理
    printf("学号:");
    scanf("%s",s->date.no);
    printf("姓名:");
    scanf("%s",s->date.name);
    printf("成绩:");
    scanf("%d",&s->date.chengji);    
    s->next=p->next;	
    p->next=s;
    printf("信息插入成功\n");
    printf("——————————————————————————\n");
}

删除

然后是删除函数
大体和插入一样,都是找到想要的结点,之后的操作改成释放内存就好(free函数)

void deletelist(linklist L)
{
    int i,n=0,j;
    linklist p,q;
    p=L->next;
    while (p!=NULL)
    {
        p=p->next;
        n++;
    }
    printf("请输入要删除学生的位置结点:");
    scanf("%d",&i);
    while(n<i)
    {
        printf("输入的结点值超过总数,请重新输入要删除学生的位置结点:");
        scanf("%d",&i);
    }
    p=L; j=1;
    while((p->next)&&(j<i))	//注意这里p是指向第i-1个结点的
    {//这里和上面其实还有给小细节,你自己细细比对一下,然后体会一下为什么(自己思考一下)
        p=p->next;
        ++j;
    }	//到这为止上面都是一样的
    q=p->next;	//q指向第i跟结点
    p->next=q->next;	//p的指针域改为指向第i+1个结点(跳过第i个,也就是p指向的)
    free(q);	//利用free函数释放内存
    printf("删除成功!\n");
    printf("————————————————————————\n");
}

查找

输入要查找的学生姓名,然后将该值存储在字符数组name中。
用p指针指向链表中第一个节点的位置。
通过while循环遍历链表,每次使用strcmp函数比较字符串是否相同,如果不同,则将 p 指向下一个节点,同时将计数j加1。如果相同,跳出循环。
如果找到了目标节点,则打印出该节点中的学号和成绩信息。否则,打印出“该表中没有该学生的信息”。

void findlist(linklist L)//查找
{
    char name[10];
    int j=1;
    linklist p;
    printf("请输入查找学生的姓名:");
    scanf("%s",name);
    p=L->next;
    while(p&&strcmp(p->date.name,name)!=0)	//这里是strcmp函数是字符串的函数,如果忘记了可以去复习一下
    {//它用来比较字符串的大小是否相同(当然这里的大小是字典序而不是长度,别弄混了)
        p=p->next;
        j++;
    }//跳出循环的条件分别是:p为空(走到链表底了)和找到了符合条件的结点
    if(p)//如果p不为空(也就是p找到了)
        printf("该学生的信息:\n学号:%s\n成绩:%d\n",p->date.no,p->date.chengji);
    else
        printf("该表中没有该学生的信息。");
}

主函数

终于完活了文章来源地址https://www.toymoban.com/news/detail-772720.html

int main()
{
    linklist L;
    int k,n;
    L=scanflist();
    printf("输入成功\n");
    printf("——————————————————————————————\n");
    while (1)
    {
        printf("使用服务输入1,结束程序输入0\n");
        scanf("%d",&k);
        if(k==1)
        {
            printf("1-打印所有学生信息\n2-插入学生信息\n3-删除学生信息\n4-姓名查找学生\n0-退出\n");
            printf("请输入使用的项目\n");
            scanf("%d",&n);
            switch (n)
            {
            case 0:printf("已返回上一界面\n");break;
            case 1:printlist(L);break;
            case 2:charulist(L);break;
            case 3:deletelist(L);break;
            case 4:findlist(L);break;
            }
        }
        else  
        {   if(k==0)
            {
                printf("谢谢使用");break;
            }
            else
                printf("指令错误,请重新输入\n");
        }
    }   
    
}

谢谢阅读,如果对你有帮助的话可以点个关注点个赞哦

到了这里,关于c语言数据结构实验:链表实现学生信息的储存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • <数据结构> 链表 - 单链表(c语言实现)

    哨兵位结点也叫哑节点。哨兵位结点 也是头结点 。该节点 不存储有效数据,只是为了方便操作 (如尾插时用带哨兵位的头结点很爽,不需要判空)。 有哨兵位结点的链表,第一个元素应该是链表第二个节点(head - next,head为哨兵位结点)对应的元素。 有哨兵位结点的链表

    2023年04月11日
    浏览(29)
  • 双向链表--C语言实现数据结构

    本期带大家一起用C语言实现双向链表🌈🌈🌈 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的;简单来说,线性表的链式存储结构生成的表,称作“链表”。 每个元素本身由两部分组成: 1、本身的信息,称

    2024年02月04日
    浏览(44)
  • 【数据结构】—C语言实现双向链表(超详细!)

                                          食用指南:本文在有C基础的情况下食用更佳                                       🔥 这就不得不推荐此专栏了:C语言                                     🍀 双向链表 前 置知识 :单链表      

    2024年02月13日
    浏览(37)
  • 【数据结构】链表OJ题(顺序表)(C语言实现)

    ✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ 🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿 🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟 🌟🌟 追风赶月莫停留 🌟🌟 🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀 🌟🌟 平芜尽处是春山

    2024年02月05日
    浏览(37)
  • (c语言实现)数据结构链表oj题(2)

    🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯C语言进阶 🔑个人信条: 🌵知行合一 🍉本篇简介::分析力扣中有关链表的部分题目. 题目来源于:牛客网-题目链接 输入一个链表,输出该链表中倒数第k个结点。 示例: 输入:1,{1,2,3,4,5} 返回值:{5} 创建两个指针: ①

    2024年02月04日
    浏览(45)
  • 【数据结构】C语言实现双向链表(带头结点、循环)

    结点定义: 接口定义: 我们将申请结点的代码封装成函数,方便后续使用 由于是带头结点的双向链表,因此在使用链表前,我们需要对链表进行初始化。 遍历链表,值得说的是,带头结点的双向链表的循环结束条件是 cur != phead 尾插时,需要先找到尾结点,然后将新结点插

    2024年02月03日
    浏览(56)
  • [C语言][数据结构][链表] 双链表的从零实现!

    目录 零.必备知识 0.1 一级指针 二级指针 0.2 双链表节点的成员列表         a. 数据         b. 后驱指针         c. 前驱指针 0.3 动态内存空间的开辟 一. 双链表的实现与销毁         1.1 节点的定义         1.2 双向链表的初始化 创建新节点         1.3 尾插       

    2024年04月17日
    浏览(31)
  • [C语言][数据结构][链表] 单链表的从零实现!

    目录 零.必备知识 1.一级指针 二级指针 2. 节点的成员列表     a.数据     b.指向下一个节点的指针. 3. 动态内存空间的开辟 (malloc-calloc-realloc) 一.单链表的实现与销毁          1.1 节点的定义         1.2 单链表的尾插         1.3 单链表的头插         1.4 单链表的尾删  

    2024年04月11日
    浏览(36)
  • c语言数据结构——链表的实现及其基本操作

    顺序表的问题及思考 问题: 中间/头部的插入删除,时间复杂度为O(N) 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到 200,我们再继续插入了5个数据,后面没有数据插

    2023年04月09日
    浏览(55)
  • 【数据结构初阶】四、线性表里的链表(带头+双向+循环 链表 -- C语言实现)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】三、 线性表里的链表(无头+单向+非循环链表 -- C语言实现)-CSDN博客  ====

    2024年02月08日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包