【数据结构与算法】深入浅出:单链表的实现和应用

 

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

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

 ✨人生如寄,多忧何为 

目录

前言

单链表的基本概念

节点

头节点

尾节点

单链表的基本操作

创建单链表

头插法:

尾插法:

插入(增)操作

 删除(删)操作:

查找(查)操作:

修改(改)操作:

遍历链表

单链表的应用场景


前言

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

单链表的基本概念

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

  • 节点

单链表中的每个节点都包含两个部分:数据域(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;
    }
}

单链表的应用场景

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

测试一下 Anthropic 宣称超过 GPT-4 的 Claude 3 Opus

测试一下 Anthropic 宣称超过 GPT-4 的 Claude 3 Opus 0. 引言1. 测试 Claude 3 Opus 0. 引言 今天测试一下 Anthropic 发布的 Claude 3 Opus。 3月4日&#xff0c;Anthropic 宣布推出 Claude 3 型号系列&#xff0c;该系列在广泛的认知任务中树立了新的行业基准。该系列包括…

Koa: 打造高效、灵活的Node.js后端 (介绍与环境部署)

在上一篇文章中&#xff0c;我们了解了Node.js的基础知识&#xff0c;今天我们将进一步学习Node.js 较新的一个轻量级Web框架Koa&#xff0c;一起创建NodeJS后端服务器吧&#xff01; 一、介绍 Koa是一个新生代Node.js Web框架&#xff0c;由Express原团队成员开发&#xff0c…

redis最新版本在Windows系统上的安装

一、说明 这次安装操作主要是根据redis官网说明&#xff0c;一步步安装下来的&#xff0c;英语比较好的同学&#xff0c;可以直接看文章底部的超链接1&#xff0c;跳到官网按步操作即可。 目前redis的最新稳定版本为redis7.2。 二、Windows环境改造 Redis在Windows上不被官方…

Django高级之-cookie-session-token

Django高级之-cookie-session-token 发展史 1、很久很久以前&#xff0c;Web 基本上就是文档的浏览而已&#xff0c; 既然是浏览&#xff0c;作为服务器&#xff0c; 不需要记录谁在某一段时间里都浏览了什么文档&#xff0c;每次请求都是一个新的HTTP协议&#xff0c; 就是请…

pytorch(四、五)用pytorch实现线性回归和逻辑斯蒂回归(分类)

文章目录 线性回归代码过程准备数据设计模型设计构造函数与优化器训练过程训练代码和结果pytorch中的Linear层的底层原理&#xff08;个人喜欢&#xff0c;不用看&#xff09;普通矩阵乘法实现Linear层实现 回调机制 逻辑斯蒂回归模型损失函数代码和结果 线性回归 代码过程 训…

【Python】成功解决TypeError: ‘tuple‘ object does not support item assignment

【Python】成功解决TypeError: ‘tuple’ object does not support item assignment &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&am…

wps没保存关闭了怎么恢复数据?数据恢复这样做

WPS文件已成为我们不可或缺的一部分。从撰写报告、制作表格到展示演讲&#xff0c;WPS系列软件为我们提供了极大的便利。然而正如任何电子设备都可能遇到的问题一样&#xff0c;WPS文件有时也可能出现损坏的情况&#xff0c;这无疑给我们的工作带来了不小的困扰。 那么当WPS文件…

Manz高压清洗机S11-028GCH-High Quality Cleaner 操作使用说明492页

Manz高压清洗机S11-028GCH-High Quality Cleaner 操作使用说明492页

基于php的用户登录实现(v1版)(持续迭代)

目录 版本说明 数据库连接 登录页面&#xff1a;login.html 登录处理实现&#xff1a;login.php 用户欢迎页面&#xff1a;welcome.php 用户注册页面&#xff1a;register.html 注册执行&#xff1a;DoRegister.php 版本说明 v1实现功能&#xff1a; 数据库连接&#x…

基于UDP实现的网络聊天室

服务器&#xff1a; #include <myhead.h> struct msg {char type;char name[20];char text[1024]; };int main(int argc, const char *argv[]) {if(argc!3){printf("input error\n");printf("./a.out IP地址 端口号\n");return -1;}//1、创建用于通…

美国国家安全局(NSA)和美国政府将Delphi/Object Pascal列为推荐政府机构和企业使用的内存安全编程语言

上周&#xff0c;美国政府发布了《回到构建块&#xff1a;通往安全和可衡量软件的道路》的报告。本报告是美国网络安全战略的一部分&#xff0c;重点关注多个领域&#xff0c;包括内存安全漏洞和质量指标。 许多在线杂志都对这份报告发表了评论&#xff0c;这些杂志强调了对 C…

css clip-path polygon属性实现直角梯形

2024.3.8今天我学习了如何用css实现直角梯形的效果&#xff0c; 效果&#xff1a; 具体实现原理&#xff1a; 一、需要三个div&#xff1a; 外面一个大的div&#xff0c;里面左右两个小的div 我们需要先把第一个div变成直角梯形&#xff1a; 大概是这样&#xff0c;设置好之…

web服务之虚拟主机功能

华子目录 概述基于IP地址的虚拟原理实验 基于不同端口号的虚拟主机原理实验 基于域名的虚拟主机原理域名解析实验 概述 如果每台运行 Linux 系统的服务器上只能运行一个网站&#xff0c;那么人气低、流量小的草根站长就要被迫承担着高昂的服务器租赁费用了&#xff0c;这显然也…

项目申报书引言部分

文献引用方式&#xff1a; 张三 等&#xff0c;2024&#xff1b; Zhang S et al.,2015&#xff1b; &#xff08;中文是中文逗号&#xff0c;英文是英文逗号&#xff09;

【你也能从零基础学会网站开发】Web建站之HTML+CSS入门篇 CSS常用属性

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 CSS常用属性…

ARM64汇编04 - 条件码

关于分支控制与条件码的作用可以去看 《CSAPP》的第 3.6 节&#xff0c;讲的非常清楚&#xff0c;建议看看&#xff0c;这里就不重复了。 我们直接使用一个例子来简单理解汇编是如何实现分支控制的&#xff1a; #include <stdio.h> #include <stdlib.h> #include…

【MATLAB第98期】基于MATLAB的MonteCarlo蒙特卡罗结合kriging克里金代理模型的全局敏感性分析模型【更新中】

【MATLAB第98期】基于MATLAB的Monte Carlo蒙特卡罗结合kriging克里金代理模型的全局敏感性分析模型【更新中】 PS:因内容涉及较多&#xff0c;所以一时半会更新不完 后期会将相关原理&#xff0c;以及多种功能详细介绍。 麻烦点赞收藏&#xff0c;及时获取更新消息。 引言 在…

Easticsearch性能优化之索引优化

Easticsearch性能优化之索引优化 一、合理的索引设计二、合理的分片和副本三、合理的索引设置 对于性能优化&#xff0c;Elasticsearch&#xff08;以下简称ES&#xff09;的索引优化是提高性能的关键因素之一。合理的设计索引&#xff0c;合理的分片和副本以及合理的缓存设置等…

VSCode报错:/bin/sh: python: command not found

背景 以前都是直接用txt写python&#xff0c;然后直接命令行运行。 这次涉及的代码较多&#xff0c;决定用编译器。 写好的一段python点击运行报错&#xff01; 问题描述 因为我本地安装的是python3&#xff0c;但是vscode用的是另一个路径的python&#xff0c;所以找不到 解…

[React 进阶系列] React Context 案例学习:使用 TS 及 HOC 封装 Context

[React 进阶系列] React Context 案例学习&#xff1a;使用 TS 及 HOC 封装 Context 具体 context 的实现在这里&#xff1a;[React 进阶系列] React Context 案例学习&#xff1a;子组件内更新父组件的状态。 根据项目经验是这样的&#xff0c;自从换了 TS 之后&#xff0c;…