线性表——(3)线性表的链式存储及其运算的实现

news2024/11/19 10:30:29

一、前言:

        由于顺序表的存储特点是用物理上的相邻关系实现逻辑上的相邻关系,它要求用连续的存储单元顺序存储线性表中各数据元素,因此,在对顺序表进行插入、删除时,需要通过移动数据元素来实现,这影响了运行效率。本节介绍线性表的链式存储结构,它不需要用地址连续的存储单元来实现,因为它不要求逻辑上相邻的两个数据元素在物理上也相邻。在链式存储结构中,数据元素之间的逻辑关系是通过“”来连接的,因此对线性表的插入、删除不需要移动数据元素

二、单链表: 

        链表是通过一组任意的存储单元来存储线性表中的数据元素的,那么怎样表示数据元素之间的线性关系呢?即如何来“链”接数据元素间的逻辑关系呢?为此,在存储数据元素时,对于每个数据元素ai,除了存放数据元素的自身信息 ai,还需要和 ai一起存放其后继数据元素 ai+1 所在的存储单元的地址,这两部分信息组成一个节点,节点的结构如图 A所示,每个数据元素皆是如此。存放数据元素自身信息的单元称为数据域存放其后继数据元素地址的单元称为指针域因此n个数据元素的线性表通过每个节点的指针域拉成了一个“链子”,称为链表。图A 所示链表的每个节点中只有一个指向后继的指针,所以称其为单链表

图A  单链表节点的结构

链表是由节点构成的,节点定义如下: 

typedef struct LNode{
	datatype data;//存放数据元素 
	struct LNode *next;//存放下一个节点的地址 
}LNode,*LinkList;

定义头指针变量:

LinkList h;//定义头指针变量

图B 所示为线性表 (a1, a2, a3, a4, a5, a6, a7, a8)对应的链式存储结构示意图。 

图B 链式存储结构示意图
图C 链表示意图

 

        当然,必须将第一个节点的地址 160 放到一个指针变量中,如H;最后一个节点没有后继,其指针域必须置空(即NULL),表明此表到此结束。这样就可以从第一个节点的地址开始“顺藤摸瓜”,找到表中的每个节点。
        作为线性表的一种存储结构,人们关心的是节点间的逻辑结构,而并不关心每个节点的实际地址,所以通常的单链表用如图C所示的形式表示而不用如图B 所示的形式表示,其中,符号“^”表示空指针(下同)。
        实际应用中通常用头指针来标识一个单链表,如单链表 L、单链表 H 等,是指某链表的第一 个节点的地址放在指针变量 L、H 中,头指针为“NULL”则表示一个空表。

        需要进一步指出的是: 上面定义的 LNode 是节点的类型,LinkList 是指向 LNode 类型节点的指针类型。为了增强程序的可读性,通常将标识一个链表的头指针定义为 LinkList 类型指针的变量,如LinkList L。当L有定义时,其值要么为 NULL(表示一个空表),要么为第一个节点的地址,即链表的头指针。将运算中用到指向某节点的指针变量说明为: LNode *类型,如 

LinkList *p;

        则语句“p=malloc(sizeof(LNode));”完成了申请一块 LNode 类型的存储单元的运算,并将其地址赋值给指针变量 p。如图D所示,指针变量 p 所指的节点为*p,*p 的类型为 LNode 型,所以该节点的数据域为(*p).data 或 p->data指针域为(*p).next 或 p->next,而语句“free(p);”则表示释放指针变量p所指的节点。 

图D 申请一个节点

三、单链表基本运算的实现: 

 💦建立单链表:

 ❤️在链表的头部插入节点建立单链表:

        链表与顺序表不同,它是一种动态管理的存储结构,链表中的每个节点占用的存储空间不是预先分配的,而是运行时系统根据需求生成的。因此,建立单链表要从空表开始,每读入一个数据元素则申请一个节点,然后插在链表的头部,图E展现了线性表(25,45,18,76,29)的链表建立过程,因为是在链表的头部插入,所以读入数据的顺序和线性表中的逻辑顺序是相反的

图E  在链表头部插入节点建立单链表
⭐单链表的建立算法(头部插入)。 
LinkList Creat_LinkList1(){
	LinkList L=NULL;//空表L为表头
	LNode *s;
	int x;			//设数据元素的类型为int型 
	scanf("%d",&x);
	while(x!=flag){//设flag为数据元素输入结束的标志 
		s=malloc(sizeof(LNode));//为插入数据元素申请空间 
		s->next=L;			//将插入数据元素置入申请到的单元中 
		L=s;
		scanf("%d",&x); 
	} 
	return L;
}  

 ❤️在单链表的尾部插入节点建立单链表:

        头部插入建立单链表虽然简单,但读入的数据元素的顺序与生成的链表中数据元素的顺序是相反的。若希望次序一致,则用尾部插入的方法。因为每次运算都是将新节点插入到链表的尾部,所以需加入一个指针 R 用来始终指向链表中的尾节点。图 F展现了在表尾部插入节点建立链表的过程。 

图F  在链表尾部插入节点建立单链表

 

         算法思路:初始状态时,头指针 H=NULL,尾指针 R=NULL,按线性表中数据元素的顺序依次读入数据元素,不是结束标志时,申请节点,将新节点插入到R 所指节点的后面,然后R指向新节点。

⭐单链表的建立算法(尾部插入)。
LinkList Creat_LinkList2(){
	LinkList *s,*R=NULL;
	int x;//设数据元素的类型为int型
	scanf("%d",&x);
	while(x!=flag){
		s=malloc(sizeof(LNode));s->data=x;//申请空间并将插入数据元素置入该单元 
		if(L==NULL){
			L=s;//第一个节点的处理 
		} 
		else{
			R->next=s;//其他节点的处理 
		} 
		R=s;//R重新指向新的尾节点 
		scanf("%d",&x); 
	} 
	if(R!=RULL){
		R->next=NULL;//对于非空表,将尾节点的next指针置空 
	} 
	return L; 
}

 ❤️在带头节点单链表的表尾插入数据元素建立单链表:

        在上面的算法中,第一个节点的处理和其他节点是不同的,原因是第一个节点加入时链表为空,它没有直接前趋节点,它的地址就是整个链表的指针,需要放在链表的头指针变量中;而其他节点有直接前趋节点,其地址放入直接前趋节点的指针域。第一个节点的问题在很多运算中都会遇到,如在链表中插入节点时,将节点插在第一个节点位置和其他节点位置是不同的,在链表中删除节点时,删除第一个节点和其他节点的处理也是不同的。
        为了方便运算,有时在链表的头部加入一个头节点,头节点的类型与数据节点一致,标识链表的头指针变量L中存放该节点的地址,这样即使是空表,头指针变量L也不为空了。头节点的加入使得第一个节点的问题不再存在,也使得空表和非空表的处理一致。
        头节点的加入完全是为了运算的方便,它的数据域无定义,指针域中存放的是第一个数据节点的地址,当空表时该指针域为空。

        图G 和图H 分别是带头节点的单链表空表和非空表的示意图。                           

 

图G  空表
图H  非空表

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

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

相关文章

玩转大数据4:大数据的崛起与应用领域探索

图片来源网络 引言 在当今数字化时代,大数据正以前所未有的速度和规模崛起。大数据的出现不仅改变了企业和组织的经营模式,也对我们的社会生活带来了深刻的影响。Java作为一种广泛使用的编程语言,在大数据领域发挥着重要的作用。本文将重点…

UniGui应用自适应PC和Mobile

先按常规方式创建UniGui PC端应用,然后按下图添加Mobile MainForm和Mobile Login Form(需要时),添加后打开网址时UNIGUI应用会根据客户端类型自动调用PC或移动端模式。

解决windows蓝牙耳机连接没有声音和声音断断续续的问题

我的蓝牙耳机连接手机一点问题没。然后连接电脑显示连接但是没声音。网上找个各种设置也不不管用。后来找到了一个办法,亲测管用。 如果你的电脑主板有wifi模块,就把WiFi天线插上。并且打开wifi开关, 就算你不用wifi,也请打开WiF…

Mac 安装 Django 并连接 MySQL

一、下载安装运行Django看官方教程就好了,网址:Django 安装_w3cschool 二、连接MySQL(我用的是pymysql和mysqlclient): 1、创建好项目后找到这个文件 2、修改当中的连接信息,将这些信息改成你自己的就好了…

Mysql的页结构详解

1.数据库的存储结构:页 索引结构为我们提供了搞笑的查找方式,索引信息和数据记录都在保存在文件上的,准确地说,是保存在“页”结构中。 1.1磁盘与内存的基本交互单位:页 InnoDB将数据划分为若干个页,Inn…

【爬虫逆向分析实战】某笔登录算法分析——本地替换分析法

前言 作者最近在做一个收集粉币的项目,可以用来干嘛这里就不展开了😁,需要进行登录换算token从而达到监控收集的作用,手机抓包发现他是通过APP进行计算之后再请求接口的,通过官网分析可能要比APP逆向方便多&#xff0…

2023-12-01 LeetCode每日一题(找出叠涂元素)

2023-12-01每日一题 一、题目编号 2661. 找出叠涂元素二、题目链接 点击跳转到题目位置 三、题目描述 给你一个下标从 0 开始的整数数组 arr 和一个 m x n 的整数 矩阵 mat 。arr 和 mat 都包含范围 [1,m * n] 内的 所有 整数。 从下标 0 开始遍历 arr 中的每…

【SpringBoot3+Vue3】七【后续2】【番外篇】- (使用docke部署)

目录 一、maven打包后端服务 1、clean 2、package 3、查看jar包 二、部署java后端服务 1、使用dockerfile构建一个java17的镜像 1.1 使用dokcerfile构建容器命令 1.2 方式一 将jar打包进容器镜像 1.3 方式二 jar不打包进容器镜像,通过映射主机目录映射方式…

C/C++ 内存管理(1)

文章目录 C/C 内存划分静态和动态内存C语言的动态内存分配函数mallocfreecallocrealloc 常见内存使用错误 C/C 内存划分 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结 束时这些存储…

【QuickSort】单边快排思路及实现

思路: (1)首先定义一个递归函数:qucikSort(int [ ] arr,int l,int r)。函数的定义:给定一个数组arr,对它在[l,r]这个区间内的元素进行排序,从而使得整个数组在[l,r]这个区间内有序。 &#xff0…

NRF24L01 无线收发模块与 Arduino 的应用

NRF24L01 是一款常用的无线收发模块,与 Arduino 兼容性良好,可以用于实现无线通信和数据传输。本文将介绍如何将 NRF24L01 模块与 Arduino 配合使用,包括硬件的连接和配置,以及相应的代码示例。 一、引言 NRF24L01 是一款基于 2.…

Linux基础项目开发1:量产工具——文字系统(四)

前言: 前面我们已经把显示系统,输入系统的框架搭建好了,那么有了输入和显示,显示的内容应该是什么呢?这节就要让我们一起对显示的内容,文字系统进行搭建。 目录 一、数据结构抽象 1.描述一个文字的位图&a…

数字图像处理(实践篇) 十六 基于分水岭算法的图像分割

目录 一 分水岭算法 二 利用OpenCV实现分水岭算法的过程 三 实践 一 分水岭算法 基于任何灰度图像都可以视为地形表面,其中高强度表示山峰和山丘,而低强度表示山谷。首先,开始用不同颜色的水(标签)填充每个孤立的山…

循环单向链表(详解)

循环单向链表原理 循环单项链表项目结构 头文件RecycleLinlList.h 头文件具体代码 #ifndef RECYCLRLINKLIST #define RECYCLRLINKLIST#include <stdio.h> #include <stdlib.h>// 宏定义 #define CIRCLELINKLIST_TRUE 1 #define CIRCLELINKLIST_FALSE 0 // 链表…

7.2 Windows驱动开发:内核注册并监控对象回调

在笔者上一篇文章《内核枚举进程与线程ObCall回调》简单介绍了如何枚举系统中已经存在的进程与线程回调&#xff0c;本章LyShark将通过对象回调实现对进程线程的句柄监控&#xff0c;在内核中提供了ObRegisterCallbacks回调&#xff0c;使用这个内核回调函数&#xff0c;可注册…

vscode如何在没有网络的情况下安装插件

vscode如何在没有网络的情况下安装插件 start 遇到没有网络的电脑&#xff0c;无法直接从插件市场安装vscode的插件。写一下 vscode 插件离线安装的方法. 解决方案 目标电脑没有可以安装插件的网络&#xff0c;那我们只能在有网络的环境下载好我们的插件。然后拷贝软件到无…

localStorage 和sessionStorage

localStorage 和 sessionStorage 是浏览器提供的两种客户端存储数据的方式&#xff1a; 生命周期&#xff1a; localStorage&#xff1a; 存储在 localStorage 中的数据在浏览器关闭后仍然保留&#xff0c;直到被显式删除或浏览器清除缓存。sessionStorage&#xff1a; 存储在 …

【零基础入门Docker】Dockerfile中的USER指令以及dockerfile命令详解

✍面向读者&#xff1a;所有人 ✍所属专栏&#xff1a;Docker零基础入门专栏 目录 第 1 步&#xff1a;创建 Dockerfile 第 2 步&#xff1a;构建 Docker 镜像 第 3 步&#xff1a;运行 Docker 容器 第 4 步&#xff1a;验证输出 dockerfile命令详解 最佳实践 默认情况下…

对el-select封装成组件使用

效果与直接使用el-select一样&#xff0c;多处用el-select显得代码冗余就进行了封装 效果图&#xff1a; el-select封装&#xff1a; <template><div class"my-select"><el-selectv-model"person.modelValue":placeholder"placehold…

【广州华锐视点】机械零件拆装VR仿真教学系统

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐走进我们的生活。在教育领域&#xff0c;VR技术的应用也日益广泛&#xff0c;为学生提供了更加生动、直观的学习体验。广州华锐视点开发的机械零件拆装VR仿真教学系统作为一种新兴的教学方式&…