深入浅出:单链表的实现和应用

news2025/1/11 22:43:12

 

🌱博客主页:青竹雾色间.

😘博客制作不易欢迎各位👍点赞+⭐收藏+➕关注

 ✨人生如寄,多忧何为 

目录

前言

单链表的基本概念

节点

头节点

尾节点

单链表的基本操作

创建单链表

头插法:

尾插法:

插入(增)操作

 删除(删)操作:

查找(查)操作:

修改(改)操作:

遍历链表

单链表的应用场景


前言

在本篇博客中,我们将深入探索一种常见的数据结构——单链表。单链表是一种线性数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。单链表的特点是插入和删除操作非常简单,但是查找和遍历操作可能会比较耗时。我们将学习单链表的基本概念、操作以及实现方式。

单链表的基本概念

下面我们来介绍一下单链表的基本概念和操作。

  • 节点

单链表中的每个节点都包含两个部分:数据域(DATA)和指针域(NEXT)。

数据域用于存储数据元素可以是数组,可以是int,甚至可以是结构体,

指针域用于存储指向下一个节点的指针

typedef int ElemType; //定义单链表结构
typedef struct Node{
    ElemType data;//数据域
    struct Node *next;//指针域
} LinkList;//初始化
  • 头节点

单链表的第一个节点称为头节点,它不包含任何数据元素,只包含一个指向第一个节点的指针。在单链表中,头节点通常被定义为全局变量或者静态变量。

//创建头结点,并将数据存入头结点中
LinkList CreateList(ElemType n){
    LinkList head = (LinkList)malloc(sizeof(struct Node));
    head->data = n;
    head->next = NULL;
    return head;
}
  • 尾节点

单链表的最后一个节点称为尾节点,它也不包含任何数据元素,只包含一个指向最后一个节点的指针。在单链表中,尾节点通常被定义为全局变量或者静态变量。

链表的尾节点NEXT指向NULL(空),因为尾部没有任何可以指向的空间了.

单链表的基本操作

单链表是一种常见的数据结构,支持以下四种基本操作:插入(增)、删除(删)、查找(查)、修改(改)。下面将逐一介绍这些操作的实现方法。

创建单链表

头插法:

我们首先创建一个头结点,然后将新节点插入到头结点的后面。具体实现时,我们可以使用指针来遍历链表,找到最后一个节点,然后将新节点插入到该节点的后面。这样就可以保证新节点始终位于链表的头部。

// 头插法
Node* insertAtHead(Node *head, int data) {
    Node *newNode = (Node*)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = head;
    return newNode;
}

尾插法:

我们首先创建一个头结点,然后将新节点插入到头结点的后面。具体实现时,我们可以使用指针来遍历链表,找到最后一个节点,然后将新节点插入到该节点的后面。这样就可以保证新节点始终位于链表的尾部。

// 尾插法
Node* insertAtTail(Node *head, int data) {
    Node *newNode = (Node*)malloc(sizeof(struct Node));
    newNode->data = data;
    if (head == NULL) { // 如果链表为空,则直接将新节点作为头结点。
        newNode->next = NULL;
        return newNode;
    } else if (head->next == NULL) { // 如果链表只有一个元素,则直接将新节点插入到该元素后面。
        head->next = newNode;
        return head;
    } else { // 否则,找到最后一个节点,然后将新节点插入到该节点的后面。
        Node *temp = head;
        while (temp->next != NULL) temp = temp->next;
        temp->next = newNode;
        return head;
    }
}

  • 插入(增)操作

          在单链表中插入一个新节点,将其链接到链表中的其他节点。

// 在指定位置插入一个新节点
void insertAtPos(Node** head, int pos, ElemType e) {
    Node* p = *head;
    int i = 1; // i表示当前节点的位置,从第二个节点开始计算
    while (i < pos && p != NULL) p = p->next, i++; // 从第二个节点开始遍历到指定位置的前一个节点
    Node* newNode = (Node*)malloc(sizeof(struct Node));
    if (newNode == NULL) exit(0); // 如果分配失败则退出程序
    newNode->data = e; // 将新节点的数据域设置为e
    if (p == NULL) *head = newNode; // 如果指定位置的前一个节点是空的,则将新节点作为新的头结点
    else newNode->next = p->next; // 否则将新节点插入到指定位置的前一个节点后面
    p->next = newNode; // 将新节点插入到链表中
}

  •  删除(删)操作

         从单链表中删除一个节点,重新连接链表中的其他节点。

  1. 若要删除的节点为头节点,直接将头节点指向下一个节点即可。
  2. 若要删除的节点不是头节点,遍历链表找到该节点的前一个节点。
  3. 将前一个节点的next指针指向要删除节点的下一个节点。

 

  • 查找(查)操作

        在单链表中查找特定的元素。

  1. 从头节点开始遍历链表,逐个比较节点的数据与目标数据是否相等。
  2. 若找到相等的节点,则返回该节点或其他需要的信息。
  3. 若遍历完整个链表仍未找到目标数据,则表示目标数据不存在于链表中。
//在单链表中查找值为x的结点
int Locate(LinkList L, int x)
{
    LinkList p;
    int j = 1;
    p = L->next;
    while (p != NULL && p->data != x)
    {
        p = p->next;
        j++;
    }
    if (p)
    {
        printf("%d在链表中,是第%d个元素", p->data - 48, j);//由于是ASCII,所以-48
    }
    else
    {
        printf("该数值不在链表里。\n");
        return 0;
    }
}

//求单链表的长度
int ListLength(LinkList L)
{
    Node* p;
    p = L->next;
    int j = 0;//计数器j
    while (p != NULL)
    {
        p = p->next;
        j++;
    }
    printf("%d", j);
    return 0;
}
  • 修改(改)操作

        更新单链表中节点的数据。

  1. 从头节点开始遍历链表,逐个比较节点的数据与目标数据是否相等。
  2. 若找到相等的节点,则将该节点的数据更新为新的数据。
//链表内容的修改,在链表中修改值为x的元素变为为k。
LinkedList LinkedListReplace(LinkedList L,int x,int k) {
    Node *p=L->next;
    int i=0;
    while(p){
        if(p->data==x){
            p->data=k;
        }
        p=p->next;
    }
    return L;
}
  • 遍历链表

在单链表中,遍历链表的操作可以通过以下步骤实现:

a. 从头结点开始遍历链表;

b. 对于每个节点,执行相应的操作(如打印数据元素)。

void Print(LinkList L) 
{
    Node* p = L->next;
    while (p) 
    {
        printf("%c ", p->data);
        p = p->next;
    }
}

单链表的应用场景

单链表在实际的软件开发中有广泛的应用,例如:

  • 数据库系统中的链表索引。

  • 实现栈和队列等其他数据结构。
  • 图算法中的邻接表表示。

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

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

相关文章

OpenGL蓝宝书第九章学习笔记:片段着色器和帧缓存

前言 本篇在讲什么 OpenGL蓝宝书第九章学习笔记之片段着色器和帧缓存 本篇适合什么 适合初学OpenGL的小白 本篇需要什么 对C语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 具有全流程的图文教学 重实践&am…

Node服务器 - koa框架

1 koa的基本使用 2 koa的参数解析 3 koa响应和错误 4 koa静态服务器 5 koa的源码解析 6 和express对比 koa的基本使用过程 const Koa require(koa)// 创建app对象 const app new Koa()// 注册中间件(middleware) // koa的中间件有两个参数: ctx/next app.use((ctx, next…

Apple Vision Pro:空间计算的未来已来,你准备好了吗?

“ 正如iPhone带我们进入移动计算时代&#xff0c;Apple Vision Pro将带我们进入空间计算时代。” 我虽然没有亲身体验&#xff0c;但观看了许多国内外第一批体验者的体验分享&#xff0c;看得出来&#xff0c;这些体验者都十分兴奋&#xff0c;根据他们的描述&#xff0c;我…

Mac安装zookeeper

文章目录 1.下载zookeeper安装包2.解压安装包3.修改配置文件4.启动服务端5.启动客户端 1.下载zookeeper安装包 https://archive.apache.org/dist/zookeeper/ 选择需要的版本下载 下载的时候要注意下载已经编译好的二进制版本 2.解压安装包 将下载的安装包解压到你想要的位…

基于Faster RCNN时间钢铁表面的缺陷检测

目标检测在许多行业中都有许多实际应用。大多数时候,在工业环境中,物体检测目标很小。因此,有效地训练目标检测模型变得非常困难。其中一个问题是钢材表面缺陷检测。即使使用深度学习,也很难高精度地解决问题。在本文中,我们将使用 PyTorch 库训练 Faster RCNN 对象检测模…

【3DsMAX】从零开始建房(5)

目录 1. 制作护栏 2. 制作梯子 3. 制作二层窗户 1. 制作护栏 选中顶部三条边线 点击“利用所选内容创建图形” 选择线性 此时我们就成功的创建了一个二维样条线 选中样条线上其中的一个点&#xff0c;移动点使线条缩短 缩小一点 渲染 同样的方法再制作一根 新建一个圆柱体 …

浅谈Spring Cloud OpenFeign

OpenFeign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用OpenFeign&#xff0c;可以做到使用HTTP请求访问远程服务&#xff0c;就像调用本地方法一样的&#xff0c;开发者完全感知不到这是在调用远程方法&#xff0c;更感知不到在访问HTTP请求。 Spring Cloud OpenFe…

临期食品电商 APP 的设计与开发

摘 要 &#xff1a; 在移动互联网和电子商务产业的快速发展中&#xff0c;越来越多的消费者开始慢慢的接触网上购 物&#xff0c;互联网经济的全面动员将席卷全球&#xff0c;各种电商应用将在时代的浪潮中层出不穷。在未来各国的 不断发展中互联网很可能会成为销售各种货物的…

在线商城前台开发环境配置

一、项目配置 node 15.14.0 官网下载 https://nodejs.org/zh-cn/download/releases npm 7.7.6 下载node后自动安装npm&#xff0c;如果版本不对就更换对应版本 npm install react7.7.6 下载项目源码 链接&#xff1a;https://www.123pan.com/s/bT07Vv-WICcv.html 解压到一…

【P50】JMeter 汇总报告(Summary Report)

文章目录 一、汇总报告&#xff08;Summary Report&#xff09;参数说明二、准备工作三、测试计划设计 一、汇总报告&#xff08;Summary Report&#xff09;参数说明 可以查看事务或者取样器在某个时间范围内执行的汇总结果 使用场景&#xff1a;用于评估测试结果 使用频率…

java boot将一组yml配置信息装配在一个对象中

其实将一组yml数据封进一个对象中才是以后的主流开发方式 我们创建一个springboot项目 找到项目中的启动类所在目录 在同目录下创建一个类 名字你们可以随便取 我这里直接叫 dataManager 然后 在yml中定义这样一组数据信息 然后 我们在类中定义三个和这个配置信息相同的字段…

全志V3S嵌入式驱动开发(触摸屏驱动)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 所谓的触摸屏&#xff0c;其实就是在普通的lcd屏幕之上&#xff0c;再加一层屏而已。这个屏是透明的&#xff0c;这样客户就可以看到下面lcd屏幕的…

想要提高办公效率,可以采用表单自定义工具

当前&#xff0c;随着社会的进步和科技的发展&#xff0c;表单自定义工具逐渐在现代化办公场所中得到重用和喜爱。因为它的灵活、简便、易操作等优势特性&#xff0c;使得其突破了传统表单制作工具的局限&#xff0c;成为广大中大型企业实现流程化管理和数字化进程的得力助手。…

UnityVR--组件5--Animation动画

目录 新建动画Animation Animation组件解释 应用举例1&#xff1a;制作动画片段 应用举例2&#xff1a;添加动画事件 Animator动画控制器 应用举例3&#xff1a;在Animator中设置动画片段间的跳转 本篇使用的API&#xff1a;Animation、Animator以及Animator类中的SetFlo…

程序语言排行榜有哪些

程序语言排名 程序语言排行NO.1Java Java是基于类的面向对象的编程语言&#xff0c;拥有跨平台、面向对象、泛型编程的特性&#xff0c;广泛应用于企业级Web应用开发和移动应用开发。任职于Sun Microsystems的詹姆斯高斯林等人于1990年代初开发Java语言的雏形&#xff0c;最初被…

超低功耗待机血压计语音IC方案,智能提示NV080C-S8

随着我国步入21世纪的步伐和改革开放的不断深入&#xff0c;我国医疗水平和人民的生活水平不断提高&#xff0c;致使我国已经成为了全球老龄化为严重的国家&#xff0c;老年人占据的比重越来越大&#xff0c;一些常见的却不容易治愈的老年性疾病的预防工作已成为现今确保老年人…

LVM逻辑卷元数据丢失恢复案例 —— 筑梦之路

Lvm常见的故障主要是pv出现异常&#xff0c;有以下几种情况 一个是pv所在的磁盘发生了lvm的元数据损坏一个是系统无法识别到pv所在的磁盘一个是系统异常&#xff0c;断电等导致重启后盘符发生变化&#xff0c;也就是系统识别的磁盘uuid发生变化&#xff0c;但是wwid还是可以对应…

4.6 Monitor概念

目录 1、对象头2、原理Monitor3、原理之Synchronized4、原理之Synchronized进阶1&#xff09;轻量级锁2&#xff09;锁膨胀3&#xff09;自旋优化4&#xff09;偏向锁5&#xff09;锁消除 1、对象头 64 位虚拟机 在加锁的过程中&#xff0c;Mark Word中的62位将会指向操作系统…

外包呆了5年终上岸,劝各位别去了...

有些测试员朋友找工作过程中问我&#xff0c;或者网上问有外包公司的offer&#xff0c;要不要去外包公司?在这里我结合我自己的经历和身边一些朋友的情况来谈谈这个问题。首先我呆过两家外包公司&#xff0c;并且身边有不少朋友是在外包公司工作。所以我只是尽量客观的分析这个…

Python 接口自动化测试导入接口无法上传文件有什么原因? 详细教程

在Python接口自动化测试中&#xff0c;上传文件通常需要使用requests库来发送HTTP请求。以下是一个示例代码来实现上传文件的功能&#xff1a; 如果你想学习自动化测试&#xff0c;我这边给你推荐一套视频&#xff0c;这个视频可以说是B站百万播放全网第一的自动化测试教程&am…