[西门子] 链表是C语言的魅力:5个你必须知道的链表的类型,格式,用法(二)

[复制链接]
查看187 | 回复0 | 2024-6-28 08:01:00 | 显示全部楼层 |阅读模式
>点击蓝字,关注我们






链表是C语言的魅力:5个你必须知道的链表的类型,格式,用法

从零开始学习C语言的结构体,带你掌握结构体的概念,类型,格式,用法和用途(二)

01
本节重点
C语言链表
链表是一种非常重要的数据结构,它可以动态地分配内存空间,实现高效的数据操作。链表由一系列的节点构成,每个节点包含了数据和一个指向下一个节点的指针。在本文中,我们将介绍链表的概念,链表的类型,链表的格式,链表的用法和用途,以及一个简单的链表的实现和应用的例子。





情景回顾:
之前讲解了关于C语言链表的类型,格式,用法这些基础的知识,接下来我们实战练习一下,根据所学知识去操作C语言链表如何使用。
链表的实现和应用的例子


为了更好地理解链表的概念和用法,我们将给出一个简单的链表的实现和应用的例子。我们将使用C语言编写一个程序,实现一个单向链表,并使用该链表来存储一些学生的信息,如姓名,学号,成绩等。我们将实现以下几个功能:
-创建链表:从键盘输入若干个学生的信息,创建一个链表,每个节点存储一个学生的信息。
-输出链表:将链表中的所有学生的信息输出到屏幕上。
-插入节点:从键盘输入一个学生的信息,将该学生插入到链表中的合适位置,使链表按照学号的升序排列。
-删除节点:从键盘输入一个学号,将链表中对应的学生删除,如果不存在该学号,输出提示信息。
-销毁链表:释放链表中所有节点占用的内存空间,结束程序。




下面是该程序的完整代码,该程序需要在VC6.0的环境下运行:















































































































































































#include <stdio.h>#include <stdlib.h>#include <string.h>
// 定义学生结构体typedef struct Student {    char name[20]; // 姓名    int id; // 学号    int score; // 成绩    struct Student* next; // 指向下一个节点的指针} Student;
// 定义头指针Student* head = NULL;
// 创建链表void createList() {    Student* p, * q; // 定义两个临时指针    int n; // 定义输入的学生个数    printf("请输入要创建的学生个数:\n");    scanf("%d", &n); // 输入学生个数    while (n > 0)   { // 循环输入学生信息        p = (Student*)malloc(sizeof(Student)); // 为新节点分配内存空间        printf("请输入学生的姓名,学号,成绩:\n");        scanf("%s,%d,%d", p->name, &p->id, &p->score); // 输入学生信息        p->next = NULL; // 将新节点的指针域置为NULL        if (head == NULL)     { // 如果链表为空,将新节点作为头节点            head = p;        }        else     { // 如果链表不为空,将新节点插入到尾部            q->next = p;        }        q = p; // 将q指向新节点        n--; // 学生个数减一    }}
// 输出链表void printList() {    Student* p; // 定义一个临时指针    p = head; // 将p指向头节点    printf("链表中的学生信息如下:\n");    while (p != NULL)   { // 循环输出每个节点的数据        printf("姓名:%s,学号:%d,成绩:%d\n", p->name, p->id, p->score);        p = p->next; // 将p指向下一个节点    }}
// 插入节点void insertNode(){    Student* p, * q, * r; // 定义三个临时指针    p = (Student*)malloc(sizeof(Student)); // 为新节点分配内存空间    printf("请输入要插入的学生的姓名,学号,成绩:\n");    scanf("%s,%d,%d", p->name, &p->id, &p->score); // 输入学生信息    q = head; // 将q指向头节点    r = NULL; // 将r置为NULL    while (q != NULL && q->id < p->id)  { // 循环找到要插入的位置        r = q; // 将r指向q的前一个节点        q = q->next; // 将q指向下一个节点    }    if (q == head)  { // 如果要插入的位置是头部        p->next = head; // 将新节点的指针域指向头节点        head = p; // 将头指针指向新节点    }    else  { // 如果要插入的位置是中间或尾部        p->next = q; // 将新节点的指针域指向q        r->next = p; // 将r的指针域指向新节点    }}
// 删除节点void deleteNode() {    Student* p, * q; // 定义两个临时指针    int id; // 定义要删除的学号    printf("请输入要删除的学生的学号:\n");    scanf("%d", &id); // 输入学号    p = head; // 将p指向头节点    q = NULL; // 将q置为NULL    while (p != NULL && p->id != id)   { // 循环找到要删除的节点        q = p; // 将q指向p的前一个节点        p = p->next; // 将p指向下一个节点    }    if (p == NULL)   { // 如果没有找到要删除的节点        printf("没有找到该学号的学生!\n");    }    else   { // 如果找到了要删除的节点        if (p == head)    { // 如果要删除的节点是头节点            head = p->next; // 将头指针指向下一个节点        }        else     { // 如果要删除的节点是中间或尾部节点            q->next = p->next; // 将q的指针域指向p的下一个节点        }        free(p); // 释放p所占用的内存空间        printf("删除成功!\n");    }}
// 销毁链表void destroyList() {    Student* p, * q; // 定义两个临时指针    p = head; // 将p指向头节点    while (p != NULL)   { // 循环释放每个节点的内存空间        q = p->next; // 将q指向下一个节点        free(p); // 释放p所占用的内存空间        p = q; // 将p指向q    }    head = NULL; // 将头指针置为NULL    printf("链表已销毁!\n");}
// 主函数int main(){    int choice=0; // 定义用户的选择    printf("欢迎使用学生信息管理系统!\n");    printf("请选择要执行的操作:\n");    printf("1.创建链表\n");    printf("2.输出链表\n");    printf("3.插入节点\n");    printf("4.删除节点\n");    printf("5.销毁链表\n");    printf("0.退出程序\n");    scanf("%d", &choice); // 输入用户的选择    while (choice != 0)   { // 循环执行用户的选择        switch (choice)     {        case 1:            createList(); // 创建链表            break;        case 2:            printList(); // 输出链表            break;        case 3:            insertNode(); // 插入节点            break;        case 4:            deleteNode(); // 删除节点            break;        case 5:            destroyList(); // 销毁链表            break;        default:            printf("无效的选择!\n");            break;        }        printf("请选择要执行的操作:\n");        printf("1.创建链表\n");        printf("2.输出链表\n");        printf("3.插入节点\n");        printf("4.删除节点\n");        printf("5.销毁链表\n");    printf("0.退出程序\n");  }}



程序测试
执行程序,选择要执行的操作:



链表的用途主要包括以下几个方面:



-实现动态数据结构:链表可以根据数据的增加或减少,动态地分配或释放内存空间,而不需要事先确定数据的大小,这样可以节省内存空间,提高内存利用率,也可以避免数组的缺点,如下标越界,空间浪费等。链表可以作为其他动态数据结构的基础,如栈,队列,树,图等。
-实现高效的数据操作:链表可以实现一些数组难以实现或效率低下的数据操作,如插入,删除,排序等。链表的插入和删除操作只需要改变指针的指向,而不需要移动大量的数据,因此效率很高。链表的排序操作也可以利用指针的特性,实现一些高效的算法,如归并排序,快速排序等。
-实现多项式的表示和运算:链表可以用来表示和运算多项式,多项式是由若干个单项式组成的代数表达式,如f(x) = 3x^2 + 2x +1。链表可以将每个单项式作为一个节点,节点中包含系数和指数两个数据域,然后将节点按照指数的降序连接起来,形成一个多项式链表。多项式链表表可以实现多项式的各种运算,如加法,减法,乘法,除法,求导,求值等。多项式的运算可以通过遍历两个多项式链表,比较和处理每个节点的系数和指数,然后生成一个新的多项式链表来实现。









想要学习C语言的朋友可以自己购买下面推荐的c语言基础从入门到精通,内容包含c语言初始到最终实战,附赠视频教学,让你轻松学习C语言。




点赞加关注,学习不迷路
微信公众号|工控小新
EPLAN电气绘图、TIA博图基础 、CAD、C语言教学、单片机基础、三菱PLC ... 每日持续更新中





发现“分享”“赞”了吗,戳我看看吧


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则