数据结构与算法——什么是单链表,链式存储结构详解

news2025/3/12 20:20:49

前面详细地介绍了顺序表,本节给大家介绍另外一种线性存储结构——链表。

链表,别名链式存储结构或单链表,用于存储逻辑关系为 "一对一" 的数据。与顺序表不同,链表不限制数据的物理存储状态,换句话说,使用链表存储的数据元素,其物理存储位置是随机的。

例如,使用链表存储 {1,2,3},数据的物理存储状态如下图所示:

链表随机存储数据

我们看到,上图根本无法体现出各数据之间的逻辑关系。对此,链表的解决方案是,每个数据元素在存储时都配备一个指针,用于指向自己的直接后继元素。如下图所示:

各数据元素配备指针

像上图这样,数据元素随机存储,并通过指针表示数据之间逻辑关系的存储结构就是链式存储结构。

链表的节点

从上图可以看到,链表中每个数据的存储都由以下两部分组成:

  1. 数据元素本身,其所在的区域称为数据域;
  2. 指向直接后继元素的指针,所在的区域称为指针域;

即链表中存储各数据元素的结构如下图所示:

上图所示的结构在链表中称为节点。也就是说,链表实际存储的是一个一个的节点,真正的数据元素包含在这些节点中,如下图所示:

链表中的节点

因此,链表中每个节点的具体实现,需要使用 C 语言中的结构体,具体实现代码为:

typedef struct Link{
    char elem; //代表数据域
    struct Link * next; //代表指针域,指向直接后继元素
}link; //link为节点名,每个节点都是一个 link 结构体

提示,由于指针域中的指针要指向的也是一个节点,因此要声明为 Link 类型(这里要写成 struct Link* 的形式)。

头节点,头指针和首元节点

其实,上图所示的链表结构并不完整。一个完整的链表需要由以下几部分构成:

1、头指针:一个普通的指针,它的特点是永远指向链表第一个节点的位置。很明显,头指针用于指明链表的位置,便于后期找到链表并使用表中的数据;

2、节点:链表中的节点又细分为头节点、首元节点和其他节点:

  • 头节点:其实就是一个不存任何数据的空节点,通常作为链表的第一个节点。对于链表来说,头节点不是必须的,它的作用只是为了方便解决某些实际问题;
  • 首元节点:由于头节点(也就是空节点)的缘故,链表中称第一个存有数据的节点为首元节点。首元节点只是对链表中第一个存有数据节点的一个称谓,没有实际意义;
  • 其他节点:链表中其他的节点;

因此,一个存储 {1,2,3} 的完整链表结构如下图所示:

完整的链表示意图

注意:链表中有头节点时,头指针指向头节点;反之,若链表中没有头节点,则头指针指向首元节点。

明白了链表的基本结构,下面我们来学习如何创建一个链表。

链表的创建(初始化)

创建一个链表需要做如下工作:

  1. 声明一个头指针(如果有必要,可以声明一个头节点);
  2. 创建多个存储数据的节点,在创建的过程中,要随时与其前驱节点建立逻辑关系;

例如,创建一个存储 {1,2,3,4} 且无头节点的链表,C 语言实现代码如下:

link * initLink(){
    link * p=NULL;//创建头指针
    link * temp = (link*)malloc(sizeof(link));//创建首元节点
    //首元节点先初始化
    temp->elem = 1;
    temp->next = NULL;
    p = temp;//头指针指向首元节点
    //从第二个节点开始创建
    for (int i=2; i<5; i++) {
     //创建一个新节点并初始化
        link *a=(link*)malloc(sizeof(link));
        a->elem=i;
        a->next=NULL;
        //将temp节点与新建立的a节点建立逻辑关系
        temp->next=a;
        //指针temp每次都指向新链表的最后一个节点,其实就是 a节点,这里写temp=a也对
        temp=temp->next;
    }
    //返回建立的节点,只返回头指针 p即可,通过头指针即可找到整个链表
    return p;
}

如果想创建一个存储 {1,2,3,4} 且含头节点的链表,则 C 语言实现代码为:

link * initLink(){
    link * p=(link*)malloc(sizeof(link));//创建一个头结点
    link * temp=p;//声明一个指针指向头结点,
    //生成链表
    for (int i=1; i<5; i++) {
        link *a=(link*)malloc(sizeof(link));
        a->elem=i;
        a->next=NULL;
        temp->next=a;
        temp=temp->next;
    }
    return p;
}

我们只需在主函数中调用 initLink 函数,即可轻松创建一个存储 {1,2,3,4} 的链表,C 语言完整代码如下:

#include <stdio.h>
#include <stdlib.h>
//链表中节点的结构
typedef struct Link{
    int  elem;
    struct Link *next;
}link;
//初始化链表的函数
link * initLink();
//用于输出链表的函数
void display(link *p);
int main() {
    //初始化链表(1,2,3,4)
    printf("初始化链表为:\n");
    link *p=initLink();
    display(p);
    return 0;
}
link * initLink(){
    link * p=NULL;//创建头指针
    link * temp = (link*)malloc(sizeof(link));//创建首元节点
    //首元节点先初始化
    temp->elem = 1;
    temp->next = NULL;
    p = temp;//头指针指向首元节点
    for (int i=2; i<5; i++) {
        link *a=(link*)malloc(sizeof(link));
        a->elem=i;
        a->next=NULL;
        temp->next=a;
        temp=temp->next;
    }
    return p;
}
void display(link *p){
    link* temp=p;//将temp指针重新指向头结点
    //只要temp指针指向的结点的next不是Null,就执行输出语句。
    while (temp) {
        printf("%d ",temp->elem);
        temp=temp->next;
    }
    printf("\n");
}

程序运行结果为:

初始化链表为:
1 2 3 4

注意,如果使用带有头节点创建链表的方式,则输出链表的 display 函数需要做适当地修改:

void display(link *p){
    link* temp=p;//将temp指针重新指向头结点
    //只要temp指针指向的结点的next不是Null,就执行输出语句。
    while (temp->next) {
        temp=temp->next;
        printf("%d",temp->elem);
    }
    printf("\n");
}

 2023新版数据结构与算法Java视频教程(上篇),java高级程序员必学的数据结构与算法
2023新版数据结构与算法Java视频教程(下篇),java高级程序员必学的数据结构与算法

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

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

相关文章

基于 SpringBoot 的高校宿舍管理系统设计与开发

1.引言 宿舍是大学生学习与生活的主要场所之一&#xff0c;宿舍管理是高校学工管理事务中 尤为重要的一项。随着我国高校招生规模的进一步扩大&#xff0c;学生总体人数的不断增加&#xff0c; 宿舍管理工作变得愈加沉重和琐碎&#xff0c;学生宿舍信息的采集、汇总、统计与分析…

火山引擎A/B测试“广告投放实验”基础能力重构实践 (DataFunTalk渠道)

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 企业在进行营销推广时&#xff0c;广告投放通常是必备环节之一。为了避免投放“乱烧钱”&#xff0c;在大规模投放前&#xff0c;企业和广告优化师都会希望在多种广…

Web3时代来临:你准备好了吗?

如果你正在浏览本文&#xff0c;那么很可能你已经是Web3时代的一部分了&#xff0c;或者至少是将要成为其中的一员。因为Web3时代即将来临&#xff0c;它将彻底改变我们对互联网的认识和使用方式。 那么&#xff0c;什么是Web3时代呢&#xff1f;简单来说&#xff0c;它是指基于…

uniapp微信小程序中使用echarts及修改报错代码

一、下载依赖 1.1、获取mpvue-echarts组件 可以先随便建个文件夹&#xff0c;然后 npm init。运行下面的命令行&#xff0c;下载依赖 npm install echarts mpvue-echarts找到node_modules\mpvue-echarts\下的文件&#xff0c;保留src文件夹&#xff0c;其他删除&#xff0c;复…

Xcode上传App Store Connect流程

一、上传前配置 1、配置好发布证书描述文件&#xff08;dis&#xff09; 2、配置好Version和Build的值&#xff0c;不配置上传过程会失败。 二、编译上传 1、菜单栏选择【Product】——【Archive】&#xff0c;开始编译&#xff0c;然后等待编译完成后&#xff0c;Xcode弹出编…

装有系统盘的U盘,在笔记本电脑不显示如何操作

codesys解压文件projectarchive失败 一般情况下&#xff0c;U盘在笔记本上不显示 如果你的笔记本插入U盘后没有显示U盘的图标&#xff0c;可能是由于以下几个原因导致的&#xff1a; 硬件问题&#xff1a;首先&#xff0c;确保U盘与笔记本电脑的USB接口连接良好。你可以尝试将…

7、sentinel使用和源码分析

一、分布式系统遇到的问题 1、服务雪崩效应 在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。如果一个服务出现了问题&#xff0c;调用这个服务就会出现线程阻塞的情况&#xff0c;此时若有大量的请求涌入&#xff0c;就会出现多条线程阻塞等待&#x…

8. 自动化测试 selenium

目录 1. 什么是自动化 2. 自动化测试金字塔 2.1 单元测试 2.2 接口自动化 2.3 UI自动化 3. 什么是 selenium 4. selenium 工作原理&#xff08;重点&#xff09; 1. 什么是自动化 自动化测试指软件测试的自动化&#xff0c;在预设状态下运行应用程序或者系统&#xff0…

51单片机学习--LED流水灯

#include <REGX52.H> #include <INTRINS.H>void Delay1ms(int t) //11.0592MHz {while(t --) {unsigned char i, j;_nop_(); //需要添加头文件i 2;j 199;do{while (--j);} while (--i);} }//延时1ms执行t次void main() {while(1){P2 0xFE; //1111 1110Delay1ms…

【Javascript】前端对文件进行md5计算再上传,以节省OSS云端存储空间

安装插件 browser-md5-file browser-md5-file 用于计算文件md5&#xff0c;文档介绍较少&#xff0c;看看就能使用↓ 使用例子 比如我用 el-upload 组件上传图片 <el-uploadaction""class"upload-box":show-file-list"false"accept"…

找回删除的MP3文件不再难,这三种方法让你轻松应对

在数字时代&#xff0c;我们常常将歌曲、照片和文档等重要数据存储在电脑或移动设备中。然而&#xff0c;有时我们会不小心删错了文件&#xff0c;比如误删了一首喜欢的MP3歌曲。这时&#xff0c;如何恢复这些被误删除的文件就变得至关重要。本文将介绍一些常见的方法和技巧&am…

labview 弹窗(子vi)

如果你遇到了需要在主vi运行时需要弹窗某个窗口(或者称为子vi,子画面)&#xff0c;而且要主画面和子画面能独立运行各自的循环程序&#xff0c;本文能给你帮助。 本文的精髓在于: wait until Donefalse,表示子VI运行的同时&#xff0c;主vi也继续运行后面的代码&#xff0c;主…

Devops7实验环境搭建(terraform-kind-k8s-argocd)

Devops7实验环境搭建(terraform-kind-k8s-argocd) 目录 实验环境 操作系统&#xff1a; CentOS8 Linux &#xff08;我本次用centos7.6&#xff09; 内存资源&#xff1a;32GB &#xff08;自己nuc机器32G内存&#xff09; 实验软件版本&#xff1a; 工具名称Version描述信息…

【正点原子STM32连载】第五十八章 T9拼音输入法实验摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第五…

Kubernetes - HPA-VPA - metrics介绍和安装 - HPA实验

目录 参考文章&#xff1a;(97条消息) Kubernetes-自动扩展器HPA、VPA、CA_hpa vpa_SRE运维充电站的博客-CSDN博客 HPA VPA 官方网址&#xff1a;autoscaler/vertical-pod-autoscaler at master kubernetes/autoscaler GitHub HPA和VPA进行扩缩容的区别&#xff1a; me…

绿水青山,节水护水我先行

为了树立人人珍惜水&#xff0c;人人节约水的良好风尚 绿萝志愿团队在7月16日在常庄刺猬河开展了2023年卫生环保志愿活动主要项目是宣传节水&#xff0c;护水志愿活动。 早上志愿者们早早的来到刺猬河旁&#xff0c;用自己带的工具准备清理河道旁的垃圾。志愿者们顶着炎炎的烈日…

Servlet 开发技术

文章目录 前言创建Servlet项目处理请求并响应处理请求text/plain&#xff0c;纯文本text/html&#xff0c;html代码application/json&#xff0c;JSON格式字符串 Servlet 生命周期Servlet在整个生命周期中被调用的方法Servlet运行原理 CORS跨域设置 前言 提示&#xff1a;这里…

rust的cargo和基本数据类型

一、cargo 1、cargo 比较大的项目就不适合用rustc进行编译了&#xff0c;此时就需要使用cargo 在安装包的时候&#xff0c;会遇到网速慢卡住的问题&#xff0c;这时候就要更换国内源或者设置代理 方法一&#xff1a;设置命令行代理 方法二&#xff1a;换源 进入用户目录下的…

linux 安装redis、配置密码及简单使用

1&#xff1a;官网下载压缩包 这里我下载的是6.2.13版本。 2&#xff1a;上传到linux服务器 a:创建redis文件夹 b:进入当前redis文件夹 c:解压缩文件 d:进入 redis-6.2.713 e:使用make 命令进行编译将.c文件编译成.o文件 编译成功之后会出现“Its a good idea to run make test…

微信原生实现一个简易的图片上传功能

一、实现原理 wx.showActionSheet()&#xff1a;显示操作菜单&#xff0c;选择是从相册选择还是相机拍摄照片wx.chooseImage()&#xff1a;从本地相册选择图片或使用相机拍照。wx.uploadFile()&#xff1a;将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求&#xff0c…