数据结构实验报告-链表

news2024/9/30 13:32:54

   

一、实验目的

1.熟练掌握链表的结构类型定义、特点。

2.熟练掌握链表的基本操作算法的实现及其算法时间复杂度的分析。

3.掌握循环链表、双向链表的结构类型定义及其基本操作算法。掌握链表的应用。

二、实验内容

1.请编写一个完整的程序,并上机实现如下操作。

(1)产生20个1~200的随机整数,并依次保存到带头结点的单链表中。

(2)计算单链表的长度,并将结果存放在头结点的数据域中,然后输出单链表。

(3)从单链表中删除与给定值 x 相等的所有结点,然后输出单链表。

(4)在(3)题的基础上将单链表降序排列,并输出结果。

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

// 定义单链表节点结构

typedef struct Node {

    int data;

    struct Node *next;

} Node;

// 定义带头结点的单链表结构

typedef struct {

    Node *head;

} LinkList;

// 创建新节点

Node* createNode(int data) {

    Node *newNode = (Node*)malloc(sizeof(Node));

    if (!newNode) {

        exit(-1);

    }

    newNode->data = data;

    newNode->next = NULL;

    return newNode;

}

// 初始化带头结点的单链表

void initLinkList(LinkList *L) {

    L->head = createNode(0); // 创建头结点,数据域可以存长度信息

}

// 产生随机整数并保存到单链表

void generateRandom(LinkList *L) {

    srand((unsigned)time(NULL));

    for (int i = 0; i < 20; ++i) {

        int randomNumber = rand() % 200 + 1;

        Node *newNode = createNode(randomNumber);

        newNode->next = L->head->next; // 插入到头结点之后

        L->head->next = newNode;

    }

}

// 计算单链表的长度

int getLength(LinkList *L) {

    int length = 0;

    Node *current = L->head->next;

    while (current) {

        length++;

        current = current->next;

    }

    L->head->data = length; // 将长度存放在头结点的数据域中

    return length;

}

// 输出单链表

void printList(LinkList *L) {

    Node *current = L->head->next;

    while (current) {

        printf("%d ", current->data);

        current = current->next;

    }

    printf("\n");

}

// 删除与给定值相等的节点

void deleteWithValue(LinkList *L, int x) {

    Node *current = L->head;

    while (current->next) {

        if (current->next->data == x) {

            Node *temp = current->next;

            current->next = temp->next;

            free(temp);

        } else {

            current = current->next;

        }

    }

}

// 降序排列单链表

void sortDescending(LinkList *L) {

    Node *current = L->head->next;

    int tempData;

    while (current) {

        Node *next = current->next;

        while (next) {

            if (current->data < next->data) {

                tempData = current->data;

                current->data = next->data;

                next->data = tempData;

            }

            next = next->next;

        }

        current = current->next;

    }

}

int main() {

    LinkList L;

    initLinkList(&L);

    // (1) 产生随机整数并保存到单链表

    generateRandom(&L);

    // (2) 计算单链表的长度并输出

    printf("Length of the list: %d\n", getLength(&L));

    printList(&L);

    // (3) 删除与给定值相等的节点

    int x;

    printf("Enter the value to delete: ");

    scanf("%d", &x);

    deleteWithValue(&L, x);

    printf("List after deleting value %d:\n", x);

    printList(&L);

    // (4) 降序排列单链表并输出

    sortDescending(&L);

    printf("List after sorting in descending order:\n");

    printList(&L);

    // 释放链表内存

    Node *temp;

    while (L.head->next) {

        temp = L.head->next;

        L.head->next = temp->next;

        free(temp);

    }

    free(L.head);

    return 0;

}

  1. 用带头结点的单链表表示学生成绩表,请编写程序,完成实验1第(3)题相应的任务。

#include <stdio.h>

#include <stdlib.h> // 包含stdlib.h以使用malloc和free

// 学生结构体定义

typedef struct Student {

    int id;

    char name[50];

    float score;

} Student;

// 学生链表节点

typedef struct StudentNode {

    Student data;

    struct StudentNode *next;

} StudentNode;

// 带头结点的学生链表

typedef struct {

    StudentNode *head;

} StudentList;

// 删除指定ID的学生

void deleteStudentById(StudentList *L, int id) {

    StudentNode *current = L->head->next;

    StudentNode *prev = L->head;

    while (current) {

        if (current->data.id == id) {

            prev->next = current->next; // 跳过当前节点

            free(current); // 释放当前节点的内存

            break;

        }

        prev = current;

        current = current->next;

    }

}

int main() {

    // 初始化带头结点的学生链表

    StudentList list;

    list.head = (StudentNode*)malloc(sizeof(StudentNode)); // 分配头结点

    if (list.head == NULL) {

        exit(-1);

    }

    list.head->next = NULL; // 初始化链表为空

    // 创建一些学生节点并添加到链表中

    Student students[] = {

        {1, "Alice", 89.5},

        {2, "Bob", 92.0},

        {3, "Cathy", 78.5},

        {4, "David", 88.0},

        {5, "Ella", 91.5}

    };

    int numStudents = sizeof(students) / sizeof(students[0]);

    for (int i = 0; i < numStudents; ++i) {

        StudentNode *newNode = (StudentNode*)malloc(sizeof(StudentNode));

        if (newNode == NULL) {

            exit(-1);

        }

        newNode->data = students[i];

        newNode->next = list.head->next;

        list.head->next = newNode;

    }

    // 打印原始链表

    printf("Original list:\n");

    StudentNode *current = list.head->next;

    while (current) {

        printf("ID: %d, Name: %s, Score: %.2f\n", current->data.id, current->data.name, current->data.score);

        current = current->next;

    }

    printf("\n");

    // 删除ID为3的学生

    int idToDelete = 3;

    deleteStudentById(&list, idToDelete);

    // 打印修改后的链表

    printf("List after deleting student with ID %d:\n", idToDelete);

    current = list.head->next;

    while (current) {

        printf("ID: %d, Name: %s, Score: %.2f\n", current->data.id, current->data.name, current->data.score);

        current = current->next;

    }

    printf("\n");

    // 释放链表内存

    while (list.head && list.head->next) {

        StudentNode *temp = list.head->next;

        list.head->next = temp->next;

        free(temp);

    }

    free(list.head); // 释放头结点

    return 0;

}

三、实验心得:
在本次实验中,我深入研究了链表的结构类型定义和特点。链表是一种基本的数据结构,其特点在于具有灵活的动态内存分配和插入、删除操作的高效性。通过实践操作,我熟练掌握了链表的定义和特点,对其内部指针关系有了更深入的理解。

其次,我通过实验实现了链表的基本操作算法,包括插入、删除、查找等操作,并对这些算法的时间复杂度进行了分析。我深入理解了链表操作算法的实现原理,能够准确评估算法的效率和性能。

此外,我还学习了循环链表和双向链表的结构类型定义以及基本操作算法。循环链表和双向链表在特定场景下具有优势,能够更灵活地应对实际问题的需求。通过实践操作,我掌握了这两种链表的操作方法,并能够根据需求合理选择使用哪种类型的链表。

最后,我意识到链表在实际应用中的重要性。在许多场景下,链表可以作为一种高效的数据结构,如实现栈、队列等其他数据结构,或者用于管理动态内存分配等。通过本次实验的学习,我深化了对链表的理解,提升了算法设计和实现能力,为今后在数据结构和算法领域的学习和研究奠定了坚实基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1979972.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于RHEL7的服务器批量安装

目录 一、项目要求 二、实验环境 三、生成kickstart自动化安装脚本 四、搭建dhcp服务并测试kickstart脚本 五、搭建pxe网络安装环境实现服务器自动部署 ​编辑 六、测试 一、项目要求 1.使用kickstart编写自动化安装脚本 2.搭建dhcp服务并测试kickstart脚本 3.搭建px…

软件设计之HTML5

软件设计之HTML5 【狂神说Java】HTML5完整教学通俗易懂 学习内容&#xff1a; 软件开发技能点参照&#xff1a;软件开发&#xff0c;小白变大佬&#xff0c;这套学习路线让你少走弯路是认真的&#xff0c;欢迎讨论 软件开发技能点参照&#xff1a;Java学习完整路线&#xff…

【doghead】mac构建 2: player 端 clion构建

准备工作 【doghead】mac构建 1 【doghead】mac: clion2024.1启动崩溃 mbp的 uv 构建ok zhangbin@zhangbin-mbp-2  ~/tet/Fargo/zhb-bifrost/Bifrost-202403/worker/third_party/libuv   main clion使用lldb cmake构建 更

SQL注入:MySQL元数据库,外网实战手工SQL注入

MySQL元数据库 MySQL的元数据库是一组特殊的数据库&#xff0c;用于存储MySQL服务器的元数据信息&#xff0c;在sql注入中较为常用为以下两种元数据库&#xff1a; information_schema&#xff1a;这个数据库包含了MySQL服务器上所有其他数据库的元数据信息。例如数据库名、表…

7 WIFI

7 WIFI 1、ESP8266模块2、烧写固件3、调试工具4、使用库函数实现wifi4.1 实现串口3和DMA的初始化4.2 利用串口3实现wifi 1、ESP8266模块 ESP8266系列无线模块是安信可科技自主研发设计的一系列高性价比WIFI SOC模组。该系列模块支持标准的IEEE802.11 b/g/n协议&#xff0c;内置…

Unity UnityWebRequest封装类

简化api调用流程&#xff0c;非常奈斯。 RestWebClient.cs using System; using System.Collections; using UnityEngine; using UnityEngine.Networking;namespace MYTOOL.RestClient {/// <summary>/// UnityWebRequest封装类/// </summary>public class RestW…

基于R语言绘制GGE双标图1

参考资料&#xff1a; 严威凯等: 双标图分析在农作物品种多点试验中的应用【作物学报】 https://cran.r-project.org/web/packages/GGEBiplots/GGEBiplots.pdf 1、安装GGEBiplots包 目前搜索到的资料多数为“GGEBiplotGUI”安装包&#xff0c;但在安装时报错&#xff0c;如下…

【独家原创】基于APO-Transformer-LSTM多特征分类预测(多输入单输出)Matlab代码

【独家原创】基于APO-Transformer-LSTM多特征分类预测&#xff08;多输入单输出&#xff09;Matlab代码 目录 【独家原创】基于APO-Transformer-LSTM多特征分类预测&#xff08;多输入单输出&#xff09;Matlab代码分类效果基本描述程序设计参考资料 分类效果 基本描述 [24年最…

【初阶数据结构题目】11.相交链表

相交链表 点击链接做题 思路&#xff1a; 如何判断链表是否相交找相交链表的起始节点 遍历两个链表&#xff0c;若尾结点相同&#xff0c;则链表一定相交。两个链表节点个数相同&#xff1a;往后遍历&#xff0c;找到相交的位置两个链表节点个数不同&#xff1a; 找两个链表的…

End-to-End Object Detection with Transformers(Detection Transformer)翻译

摘要 我们提出了一种新方法&#xff0c;将目标检测视为直接的集合预测问题。我们的方法简化了检测流程&#xff0c;有效消除了对许多手工设计组件的需求&#xff0c;如非极大值抑制过程或锚框生成&#xff0c;这些组件显式编码了我们对任务的先验知识。新框架称为检测变换器&a…

Meta Reality Labs:巨额亏损背后的挑战与展望

一、财务概况 自2020年以来,Meta的Reality Labs部门累计亏损已超过450亿美元,其中2023年的亏损达到160亿美元,2024年第一季度亏损38亿美元,分析师预计第二季度亏损可能接近50亿美元。尽管投入巨大,Reality Labs的收入却呈现下降趋势,与不断增加的支出形成鲜明对比。 二…

QT使用V4L2摄像头采集数据

前言 之前我们已经实现了摄像头用V4L2框架采集一张图片&#xff0c;现在就是实现用摄像头采集视频流&#xff08;本质一张图片就是一帧&#xff0c;很多张图片就是很多帧&#xff0c;拼起来就是一个视频&#xff09;。 本部分需要大家有一点QT相关的知识&#xff0c;整体框架还…

CSP 2020 第三题:表达式

牛客网题目 题目内容&#xff1a; 示例1 输入 x1 x2 & x3 | 3 1 0 1 3 1 2 3输出 1 1 0题意&#xff1a; 给出后续表达式&#xff0c;需要计算这个表达式的值&#xff0c;并让某几个变量值取反&#xff0c;再输出新的表达式的值&#xff08;变量改变均为临时的&#xff…

基于Orangepi全志H616学习Python3

目录 一、功能需求 二、Python的安装和环境搭建 三、Python的基础学习 3.1 Python的特点&#xff1a; 3.2 编写并运行第一个Python程序&#xff1a; 3.3 标识符&#xff1a; 3.4 关键字&#xff1a; 3.5 注释&#xff1a; 3.6 行与缩进&#xff1a; 3.7 多行语句&…

虚拟机(CentOS7)安装jenkins

centos7安装jenkins 前提条件&#xff0c;安装jdk与maven 1、JDK17安装 # 进入系统管理员 sudo root # 进入对应文件夹下 cd /usr/local # 下载jdk17 wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.rpm # rpm命令安装下载的jdk17 rpm -ivh jdk-17_li…

从根儿上学习spring 七 之run方法启动第四段(1)

图1 一步一步我们转眼间来到了第四部分&#xff0c;这是spring最核心的部分包含了bean的整个生命周期过程&#xff0c;不过大家不用担心如果内容过长我会分多个小节来说明以防止一篇文章让大家看晕看累难以吸收理解。让我们直接进入正题。 我们先进入图1的refreshContext方法看…

PEX实验

一、kickstart自动安装脚本制作 1.关闭本机dhcp服务 2.安装图形化生成kickstart自动安装脚本的工具 3.配置http服务 下载httpd 启动并挂载 3.启动图形制作工具 system-config-kickstart 4.配置ks.cfg 5.拷贝到/var/www/html/中去 6.浏览器测试 配置dhcp服务 测试 二.搭建pex…

【JVM基础11】——垃圾回收-说一下JVM的分代回收?

目录 1- 引言&#xff1a;分代回收1-1 什么是分代回收&#xff08;What&#xff09;1-2 为什么要用分代回收&#xff1f;&#xff08;Why&#xff09; 2- ⭐核心&#xff1a;分代回收工作机制2-1 工作机制2-2 MinorGC、Mixed GC、FullGC的区别是什么 3- 总结3-1 说一下 JVM 的分…

【Java 第三篇章】注释、数据类型、运算符

一、注释 Java 中的注释有三种方式&#xff1a;单行注释、多行注释、文档注释。 1、单行注释语法 // 这是单行注释2、多行注释 /** 这是多行注释*/3、文档注释 /*** 这是文档注释*/二、数据类型 Java 中有 8 中基本数据类型&#xff0c;分别为&#xff1a;整型&#xff08;b…

数据结构实验报告-排序

桂 林 理 工 大 学 实 验 报 告 一、实验名称 实验8 排序 二、实验内容&#xff1a; 分别采用直接插人排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序、归并排序等排序算法对简单的整型数组进行排序,并输出排序结果。 源码&#xff1a;#include <iostre…