目录

实验一 线性表的基本操作

一、实验目的

二、实验内容

三、实验提示

四、实验要求

五、实验代码如下:

(一)链表的构建及初始化

学生信息结构体定义

定义元素类型

链表节点结构体定义

初始化链表

(二)创建一个新节点

(三)根据指定学生个数,逐个输入学生信息

函数参数

查找第i-1个节点

检查插入位置的合法性

创建新节点并插入链表

(四)逐个显示学生表中所有学生的相关信息

(五)根据姓名进行查找,返回此学生的学号和成绩

(六)根据指定的位置可返回相应的学生信息(学号,姓名,成绩);

(七) 给定一个学生信息,插入到表中指定的位置

 (八)删除指定位置的学生记录

 (九)退出程序,释放链表

(十)main函数

运行截图:

六、整体代码如下: 


实验一 线性表的基本操作

一、实验目的

1、掌握线性表的定义;

2、掌握线性表的基本操作,如建立、查找、插入和删除等。

二、实验内容

定义一个包含学生信息(学号,姓名,成绩)的顺序表和链表,使其具有如下功能:

(1) 根据指定学生个数,逐个输入学生信息;

(2) 逐个显示学生表中所有学生的相关信息;

(3) 根据姓名进行查找,返回此学生的学号和成绩;

(4) 根据指定的位置可返回相应的学生信息(学号,姓名,成绩);

(5) 给定一个学生信息,插入到表中指定的位置;

(6) 删除指定位置的学生记录;

(7) 统计表中学生个数。

三、实验提示

学生信息的定义:

typedef struct {

    char no[8];   //8位学号

    char name[20]; //姓名

    int grade;     //成绩

}Student;

顺序表的定义

typedef  struct {

  Student  *elem;     //指向数据元素的基地址

  int  length;       //线性表的当前长度                                                           

 }SqList;

链表的定义:

typedef struct LNode{

     Student   data;       //数据域

     struct LNode  *next;   //指针域

}LNode,*LinkList;

四、实验要求

(1) 程序要添加适当的注释,程序的书写要采用缩进格式。

(2) 程序要具有一定的健壮性,即当输入数据非法时,程序也能适当地做出反应,如插入删除时指定的位置不对等等。

(3) 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。

(4) 根据实验报告模板详细书写实验报告,在实验报告中给出链表根据姓名进行查找的算法和插入算法的流程图。

五、实验代码如下:

(一)链表的构建及初始化

学生信息结构体定义

  • typedef struct定义了一个名为student的结构体,用于存储单个学生的信息。
    • char no[8];:存储8位学号。
    • char name[20];:存储学生姓名,最多19个字符加上一个字符串结束符\0
    • double score;:存储学生的成绩,类型为double以支持小数。

定义元素类型

  • typedef student ElemType;:定义了一个新的类型名ElemType,其实就是student结构体。这样做可以增加代码的可读性和可维护性,也方便以后对元素类型的修改。

链表节点结构体定义

  • typedef struct LNode定义了链表节点的结构体,每个节点包括:
    • ElemType data;:数据域,用于存储一个ElemType类型的数据,在这里即为student结构体实例。
    • struct LNode* next;:指针域,用于指向链表中下一个节点的地址。如果这是链表的最后一个节点,则nextNULL

初始化链表

  • bool InitList(LN* L)函数用于初始化一个链表。
    • 首先,使用malloc分配一个LNode类型节点的内存空间给链表的头节点。头节点通常不存储有效数据,它的作用是作为链表的入口点。
    • 如果内存分配失败(即malloc返回NULL),则输出错误信息并返回false
    • 成功分配内存后,将头节点的next指针设置为NULL,表示链表为空。
    • 返回true表示链表初始化成功。
// 学生信息结构体定义
typedef struct {
    char no[8];   // 8位学号
    char name[20]; // 姓名
    double score;  // 成绩
} student;

// 定义元素类型
typedef student ElemType;

// 链表节点结构体定义
typedef struct LNode {
    ElemType data;       // 数据域,存储学生信息
    struct LNode* next;  // 指针域,指向下一个节点
} LNode, *LN;

// 初始化链表
bool InitList(LN* L) {
    *L = (LNode*)malloc(sizeof(LNode)); // 分配头节点空间
    if (!(*L)) { // 内存分配失败的处理
        printf("malloc fail");
        return false;
    }
    (*L)->next = NULL; // 头节点的指针域设置为空
    return true;
}

(二)创建一个新节点

  • LN BuySListNode(ElemType x)函数用于创建一个新的链表节点,并存储提供的学生信息x
    • 与初始化链表类似,先使用malloc为新节点分配内存空间。
    • 如果内存分配失败,则输出错误信息并通过exit(-1);退出程序。
    • 成功分配内存后,将传入的学生信息x赋值给新节点的数据域,同时设置新节点的指针域为NULL
    • 返回新创建的节点。
// 创建一个新节点,存储学生信息
LN BuySListNode(ElemType x) {
    LN newnode = (LN)malloc(sizeof(LNode)); // 为新节点分配空间
    if (!newnode) { // 内存分配失败的处理
        printf("malloc fail");
        exit(-1);
    }
    newnode->data = x; // 设置数据域
    newnode->next = NULL; // 新节点的指针域设置为空
    return newnode;
}

(三)根据指定学生个数,逐个输入学生信息

函数参数

  • LN L:指向链表头节点的指针。
  • int i:指定的插入位置,位置编号从1开始。
  • ElemType e:要插入的学生信息,ElemType是学生信息结构体student的别名。

查找第i-1个节点

  • 从链表的头节点开始遍历,目标是找到第i-1个节点。这是因为在单链表中插入一个新节点时,需要修改第i-1个节点的next指针,使其指向新插入的节点。
  • LN p = L;初始化遍历指针p为链表的头节点。
  • int j = 0;初始化计数器j,用来记录当前遍历到链表的第几个节点。
  • 使用while循环移动p,直到p指向第i-1个节点或链表结束。循环条件p && j < i - 1确保只有当p非空且j小于i-1时循环继续。

检查插入位置的合法性

  • 在尝试插入新节点前,需要确认找到的位置是合法的。
  • if (!p || j > i - 1) return false;如果p为空,或j大于i-1,说明指定的插入位置i无效(例如,超出了链表长度)。此时函数返回false,表示插入操作失败。

创建新节点并插入链表

  • LN s = BuySListNode(e);创建一个新的链表节点s,并将要插入的学生信息e存储于此节点。BuySListNode函数负责分配内存,并初始化新节点的数据和指针域。
  • s->next = p->next;将新节点snext指针设置为pnext指针当前指向的节点,即将s链接到链表中的正确位置。
  • p->next = s;更新第i-1个节点的next指针,使其指向新插入的节点s。这样,节点s就被正确插入到链表的第i个位置。
  • 返回true表示插入操作成功。

// 输入学生信息
void Input(ElemType* e) {
    printf("学号: "); scanf("%s", e->no);
    printf("姓名: "); scanf("%s", e->name);
    printf("成绩: "); scanf("%lf", &e->score);
    printf("输入完成\n\n");
}

// 在链表的指定位置插入学生信息
bool ListInsert(LN L, int i, ElemType e) {
    LN p = L;
    int j = 0;
    // 查找第i-1个节点
    while (p && j < i - 1) {
        p = p->next;
        ++j;
    }
    // 插入位置不合法的处理
    if (!p || j > i - 1) return false;
    // 创建新节点并插入链表
    LN s = BuySListNode(e);
    s->next = p->next;
    p->next = s;
    return true;
}

// 输入学生信息
printf("请输入要录入的学生人数:");
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
     printf("第%d个学生:\n", i);
     ElemType* a = (ElemType*)malloc(sizeof(ElemType)); // 动态分配每个学生的空间
     if (a == NULL) {
           printf("内存分配失败\n");
           exit(-1);
        }
          Input(a); // 修改Input函数以接受ElemType指针
          ListInsert(L, i, *a); // 插入链表
 }

(四)逐个显示学生表中所有学生的相关信息

// 输出学生信息
void Output(ElemType e) {
    printf("学号:%-10s\n姓名:%-20s\n成绩:%-10.2lf\n\n", e.no, e.name, e.score);
}

// 获取链表中指定位置的学生信息
void GetElem(LN L, int i, ElemType* e) {
    LN p = L->next; // 从头节点的下一个节点开始
    int j = 1;
    // 查找第i个节点
    while (p && j < i) {
        p = p->next;
        ++j;
    }
    // 若位置i不合法,则直接返回
    if (!p || j > i) return;
    *e = p->data; // 将找到的节点的数据复制到e指向的变量中
}

for (i = 1; i <= n; ++i) {
    GetElem(L, i, &b);
    Output(b);
}

(五)根据姓名进行查找,返回此学生的学号和成绩

// 根据姓名查找学生信息
bool Search(LN L, char str[], LN* p) {
    *p = L->next; // 从头节点的下一个节点开始查找
    while (*p) {
        // 比较当前节点学生姓名是否与给定姓名相同
        if (!strcmp((*p)->data.name, str))
            return true;
        *p = (*p)->next;
    }
    return false; // 未找到指定姓名的学生
}

// 根据姓名查找学生
printf("请输入要查找的学生姓名: ");
scanf("%s", str);
if (Search(L, str, &t)) {
    Output(t->data);
}
else {
    printf("没有此学生的信息!\n");
}

(六)根据指定的位置可返回相应的学生信息(学号,姓名,成绩);

  1. 设置起始节点

    LN p = L->next:定义并初始化一个指针变量p,用于遍历链表。它被设置为指向链表的第一个元素节点(头节点的下一个节点)。
  2. 初始化计数器

    int j = 1;定义并初始化计数器j为1,用于追踪当前遍历到的节点位置。
  3. 遍历链表定位元素

    • 使用while循环遍历链表,直到找到第i个节点或到达链表末尾(p变为NULL)。
    • 循环条件p && j < i确保了只有当当前节点p非空且计数器j小于目标位置i时,循环才会继续。在每次循环中,p会更新为下一个节点(p = p->next;),同时计数器j增加1(++j;)。
  4. 检查位置合法性

    在循环结束后,通过检查if (!p || j > i)来确定是否成功找到了第i个节点。如果pNULLj大于i,意味着目标位置i超出了链表的长度,此时函数直接返回,不进行任何操作。
  5. 复制节点数据

    如果成功找到了第i个节点(即p非空且j等于i),则将该节点的数据(p->data)复制到通过参数e传入的变量中(*e = p->data;)。
// 获取链表中指定位置的学生信息
void GetElem(LN L, int i, ElemType* e) {
    LN p = L->next; // 从头节点的下一个节点开始
    int j = 1;
    // 查找第i个节点
    while (p && j < i) {
        p = p->next;
        ++j;
    }
    // 若位置i不合法,则直接返回
    if (!p || j > i) return;
    *e = p->data; // 将找到的节点的数据复制到e指向的变量中
}

// 显示指定位置的学生信息
printf("请输入要查询的位置:");
scanf("%d", &d1);
GetElem(L, d1, &c);
Output(c);

(七) 给定一个学生信息,插入到表中指定的位置

  1. 查找第i-1个节点

    • 函数开始时,首先设置一个指针p来遍历链表,从链表的头节点L开始。同时,设置一个计数器j来记录当前遍历到的位置,初始化为0。
    • 使用while循环,条件是p非空并且j < i - 1,即尝试移动p直到它指向第i-1个节点。这是因为在链表中插入一个新节点,需要修改前一个节点的next指针。
    • 每次循环中,p移动到下一个节点(p = p->next),并且计数器j递增。
  2. 检查插入位置的合法性

    • 循环结束后,使用if (!p || j > i - 1)来检查是否成功找到了有效的插入位置。如果p为空(即到达了链表末尾之后)或者j超过了i-1(这通常不会发生,因为循环条件限制了j < i - 1),则认为插入位置不合法,函数返回false
  3. 创建新节点并插入链表

    • 通过调用BuySListNode(e)创建一个新的链表节点s,并将要插入的学生信息e填充到该节点的数据域中。
    • 将新节点snext指针设置为p的下一个节点,即p->next,这样新节点s就链接到了链表中的正确位置。
    • 更新pnext指针,使其指向新节点s,从而将s正式插入到链表中。
    • 最后,函数返回true,表示插入操作成功。
// 在链表的指定位置插入学生信息
bool ListInsert(LN L, int i, ElemType e) {
    LN p = L;
    int j = 0;
    // 查找第i-1个节点
    while (p && j < i - 1) {
        p = p->next;
        ++j;
    }
    // 插入位置不合法的处理
    if (!p || j > i - 1) return false;
    // 创建新节点并插入链表
    LN s = BuySListNode(e);
    s->next = p->next;
    p->next = s;
    return true;
}

//给定一个学生信息,插入到表中指定的位置;
printf("请输入要插入的位置:");
scanf("%d", &id2);
printf("输入要插入的人数:");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
	printf("请输入第 %d 个学生:\n", i);
	Input(&a);
	if (ListInsert(ps, id2, &a))
	{
		puts("插入成功");
	}
	else
	{
		puts("插入失败\n");
	}
}

 (八)删除指定位置的学生记录

  • 初始化指针和计数器

    • LN p = L:定义并初始化一个指针变量p,用于遍历链表,初始指向链表的头节点。
    • LN q:定义一个指针变量q,用于临时存储待删除节点的地址。
    • int j = 0:定义并初始化计数器j为0,用于记录当前p指针所在的节点位置。
  • 查找第i-1个节点

    • 使用while循环移动p指针,目的是定位到第i-1个节点。这是因为在单链表中删除一个节点时,需要修改其前驱节点的next指针。
    • 循环条件p->next && j < i - 1确保了只有当p的下一个节点存在(即p不是尾节点)且j小于目标位置i减1时,循环才会继续。
  • 检查删除位置的合法性

    • if (!(p->next) || j > i - 1):这个条件检查是否存在第i个节点。
  • 删除节点

    • q = p->next:将q指向要删除的节点,即第i个节点,也就是p的下一个节点。
    • p->next = q->next:将pnext指针指向q的下一个节点,从而在链表中跳过q节点,实现删除操作。
    • free(q):释放q节点占用的内存空间。free是C语言标准库函数,用于释放之前通过malloccallocrealloc函数分配的内存。
  • 返回删除成功的标志

    • 函数最后返回true,表示节点删除成功。

// 删除链表中指定位置的学生记录
bool ListDelete(LN L, int i) {
    LN p = L, q;
    int j = 0;
    // 查找第i-1个节点
    while (p->next && j < i - 1) {
        p = p->next;
        ++j;
    }
    // 删除位置不合法的处理
    if (!(p->next) || j > i - 1) return false;
    q = p->next; // q指向要删除的节点
    p->next = q->next; // 删除节点q
    free(q); // 释放节点q的内存空间
    return true;
}

 (九)退出程序,释放链表

  1. 定义变量

    • LN current = *L;:定义一个指针变量current用于遍历链表,它被初始化为指向链表的头节点。
    • LN next;:定义一个指针变量next,用于临时存储当前节点的下一个节点的地址,以便在释放当前节点内存后仍能继续遍历链表。
  2. 遍历链表

    使用while循环遍历链表,循环条件current != NULL确保只要当前节点非空,循环就继续。
  3. 保存下一个节点的地址

    在释放当前节点内存之前,需要先保存下一个节点的地址,因为一旦当前节点被释放,就无法通过当前节点的next指针访问下一个节点了。
  4. 释放当前节点

    使用free(current);释放当前节点占用的内存。free函数是C语言标准库中的函数,用于释放之前通过malloccallocrealloc函数分配的内存。
  5. 移动到下一个节点:将current更新为next,即移动到链表的下一个节点,为下一次循环的执行做准备。这一步是在current = next;这行代码中完成的。

  6. 将链表头指针设置为NULL:在链表的所有节点都被释放后,最后一步是将链表的头指针设置为NULL,表示链表为空。这是通过*L = NULL;这行代码完成的。

// 释放链表占用的内存
void FreeList(LN* L) {
    LN current = *L; // current用于遍历链表
    LN next;

    while (current != NULL) {
        next = current->next; // 保存下一个节点的指针
        free(current); // 释放当前节点
        current = next; // 移动到下一个节点
    }

    *L = NULL; // 最后将链表头指针设置为NULL
}

if (choose == 9)
{
    FreeList(&L);
    break; // 选择9则退出程序
    // 用户选择退出程序前释放链表
}

(十)main函数

int main() {
    LN L, t = NULL; // L是链表头指针,t用于临时存储查找到的节点
    ElemType a, b, c; // 用于临时存储和操作学生信息

    printf("\n1.构造链表\n");
    printf("2.输入学生信息\n");
    printf("3.显示学生表信息\n");
    printf("4.根据姓名进行查找\n");
    printf("5.显示指定的位置学生信息\n");
    printf("6.在指定位置插入学生信息\n");
    printf("7.删除指定位置的学生记录\n");
    printf("8.统计学生人数\n");
    printf("9.退出\n\n");

    int n = 0, choose = 0, i = 0, d1 = 0; // n用于记录学生总数,choose用于用户选择,d1用于临时存放用户输入的位置
    char str[20]; // 用于存放用户查找时输入的姓名
    while (1) {
        printf("请选择:");
        scanf("%d", &choose);
        if (choose == 9)
        {
            break; // 选择9则退出程序
            // 用户选择退出程序前释放链表
            FreeList(&L);
        }
        switch (choose) {
        case 1: 
            // 初始化链表
            if (!InitList(&L)) {
                printf("链表初始化失败。\n");
                return 1;
            }
            else
            printf("链表已初始化。\n");
            break;
        Case 2: // 输入学生信息
            printf("请输入要录入的学生人数:");
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) {
                printf("第%d个学生:\n", i);
                ElemType* a = (ElemType*)malloc(sizeof(ElemType)); // 动态分配每个学生的空间
                if (a == NULL) {
                    printf("内存分配失败\n");
                    exit(-1);
                }
                Input(a); // 修改Input函数以接受ElemType指针
                ListInsert(L, i, *a); // 插入链表
            }
        Case 3: // 显示所有学生信息
            for (i = 1; i <= n; ++i) {
                GetElem(L, i, &b);
                Output(b);
            }
        
        Case 4: // 根据姓名查找学生
            printf("请输入要查找的学生姓名: ");
            scanf("%s", str);
            if (Search(L, str, &t)) {
                Output(t->data);
            }
            else {
                printf("没有此学生的信息!\n");
            }
        Case 5: // 显示指定位置的学生信息
            printf("请输入要查询的位置:");
            scanf("%d", &d1);
            GetElem(L, d1, &c);
            Output(c);
        Case 6: // 在指定位置插入学生信息
            printf("请输入要插入的位置:");
            scanf("%d", &d1);
            printf("请输入学生信息:\n");
            Input(&c);
            if (ListInsert(L, d1, c)) {
                ++n;
                printf("插入成功\n");
            }
            else {
                printf("插入失败\n");
            }
        Case 7: // 删除指定位置的学生记录
            printf("请输入要删除的位置:");
            scanf("%d", &d1);
            if (ListDelete(L, d1)) {
                --n;
                printf("删除成功\n");
            }
            else {
                printf("删除失败\n");
            }
        Case 8: // 统计学生人数
            printf("已录入的学生个数为:%d\n\n", n);
            break;
        default:
            printf("无效选项\n");
        }
    }

    return 0;
}

运行截图:

六、整体代码如下: 

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#define Case break;case

// 学生信息结构体定义
typedef struct {
    char no[8];   // 8位学号
    char name[20]; // 姓名
    double score;  // 成绩
} student;

// 定义元素类型
typedef student ElemType;

// 链表节点结构体定义
typedef struct LNode {
    ElemType data;       // 数据域,存储学生信息
    struct LNode* next;  // 指针域,指向下一个节点
} LNode, *LN;

// 初始化链表
bool InitList(LN* L) {
    *L = (LNode*)malloc(sizeof(LNode)); // 分配头节点空间
    if (!(*L)) { // 内存分配失败的处理
        printf("malloc fail");
        return false;
    }
    (*L)->next = NULL; // 头节点的指针域设置为空
    return true;
}

// 创建一个新节点,存储学生信息
LN BuySListNode(ElemType x) {
    LN newnode = (LN)malloc(sizeof(LNode)); // 为新节点分配空间
    if (!newnode) { // 内存分配失败的处理
        printf("malloc fail");
        exit(-1);
    }
    newnode->data = x; // 设置数据域
    newnode->next = NULL; // 新节点的指针域设置为空
    return newnode;
}

// 在链表的指定位置插入学生信息
bool ListInsert(LN L, int i, ElemType e) {
    LN p = L;
    int j = 0;
    // 查找第i-1个节点
    while (p && j < i - 1) {
        p = p->next;
        ++j;
    }
    // 插入位置不合法的处理
    if (!p || j > i - 1) return false;
    // 创建新节点并插入链表
    LN s = BuySListNode(e);
    s->next = p->next;
    p->next = s;
    return true;
}

// 输入学生信息
void Input(ElemType* e) {
    printf("学号: "); scanf("%s", e->no);
    printf("姓名: "); scanf("%s", e->name);
    printf("成绩: "); scanf("%lf", &e->score);
    printf("输入完成\n\n");
}

// 输出学生信息
void Output(ElemType e) {
    printf("学号:%-10s\n姓名:%-20s\n成绩:%-10.2lf\n\n", e.no, e.name, e.score);
}

// 根据姓名查找学生信息
bool Search(LN L, char str[], LN* p) {
    *p = L->next; // 从头节点的下一个节点开始查找
    while (*p) {
        // 比较当前节点学生姓名是否与给定姓名相同
        if (!strcmp((*p)->data.name, str))
            return true;
        *p = (*p)->next;
    }
    return false; // 未找到指定姓名的学生
}

// 删除链表中指定位置的学生记录
bool ListDelete(LN L, int i) {
    LN p = L, q;
    int j = 0;
    // 查找第i-1个节点
    while (p->next && j < i - 1) {
        p = p->next;
        ++j;
    }
    // 删除位置不合法的处理
    if (!(p->next) || j > i - 1) return false;
    q = p->next; // q指向要删除的节点
    p->next = q->next; // 删除节点q
    free(q); // 释放节点q的内存空间
    return true;
}

// 获取链表中指定位置的学生信息
void GetElem(LN L, int i, ElemType* e) {
    LN p = L->next; // 从头节点的下一个节点开始
    int j = 1;
    // 查找第i个节点
    while (p && j < i) {
        p = p->next;
        ++j;
    }
    // 若位置i不合法,则直接返回
    if (!p || j > i) return;
    *e = p->data; // 将找到的节点的数据复制到e指向的变量中
}


// 释放链表占用的内存
void FreeList(LN* L) {
    LN current = *L; // current用于遍历链表
    LN next;

    while (current != NULL) {
        next = current->next; // 保存下一个节点的指针
        free(current); // 释放当前节点
        current = next; // 移动到下一个节点
    }

    *L = NULL; // 最后将链表头指针设置为NULL
}

int main() {
    LN L, t = NULL; // L是链表头指针,t用于临时存储查找到的节点
    ElemType a, b, c; // 用于临时存储和操作学生信息

    printf("\n1.构造链表\n");
    printf("2.输入学生信息\n");
    printf("3.显示学生表信息\n");
    printf("4.根据姓名进行查找\n");
    printf("5.显示指定的位置学生信息\n");
    printf("6.在指定位置插入学生信息\n");
    printf("7.删除指定位置的学生记录\n");
    printf("8.统计学生人数\n");
    printf("9.退出\n\n");

    int n = 0, choose = 0, i = 0, d1 = 0; 
    // n用于记录学生总数,choose用于用户选择,d1用于临时存放用户输入的位置
    char str[20]; // 用于存放用户查找时输入的姓名
    while (1) {
        printf("请选择:");
        scanf("%d", &choose);
        if (choose == 9)
        {
            FreeList(&L);
            break; // 选择9则退出程序
            // 用户选择退出程序前释放链表
        }
        switch (choose) {
        case 1: 
            // 初始化链表
            if (!InitList(&L)) {
                printf("链表初始化失败。\n");
                return 1;
            }
            else
            printf("链表已初始化。\n");
            break;
        Case 2: // 输入学生信息
            printf("请输入要录入的学生人数:");
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) {
                printf("第%d个学生:\n", i);
                ElemType* a = (ElemType*)malloc(sizeof(ElemType));
                // 动态分配每个学生的空间
                if (a == NULL) {
                    printf("内存分配失败\n");
                    exit(-1);
                }
                Input(a); // 修改Input函数以接受ElemType指针
                ListInsert(L, i, *a); // 插入链表
            }
        Case 3: // 显示所有学生信息
            for (i = 1; i <= n; ++i) {
                GetElem(L, i, &b);
                Output(b);
            }
        
        Case 4: // 根据姓名查找学生
            printf("请输入要查找的学生姓名: ");
            scanf("%s", str);
            if (Search(L, str, &t)) {
                Output(t->data);
            }
            else {
                printf("没有此学生的信息!\n");
            }
        Case 5: // 显示指定位置的学生信息
            printf("请输入要查询的位置:");
            scanf("%d", &d1);
            GetElem(L, d1, &c);
            Output(c);
        Case 6: // 在指定位置插入学生信息
            printf("请输入要插入的位置:");
            scanf("%d", &d1);
            printf("请输入学生信息:\n");
            Input(&c);
            if (ListInsert(L, d1, c)) {
                ++n;
                printf("插入成功\n");
            }
            else {
                printf("插入失败\n");
            }
        Case 7: // 删除指定位置的学生记录
            printf("请输入要删除的位置:");
            scanf("%d", &d1);
            if (ListDelete(L, d1)) {
                --n;
                printf("删除成功\n");
            }
            else {
                printf("删除失败\n");
            }
        Case 8: // 统计学生人数
            printf("已录入的学生个数为:%d\n\n", n);
            break;
        default:
            printf("无效选项\n");
        }
    }

    return 0;
}

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐