【数据结构与算法 3】单链表

数据结构之单链表非常详细介绍(适合小白) 数据结构深度学习之单链表非常详解解读~~~一万多字详解 阅读详情

一、链表的特点

1、链表是一种非线性、非顺序的物理结构,是由多个节点组成。

2、链表采用的是“见缝插针”的存储方法,不要求内存连续,靠next指针关联起来。

3、链表的物理存储方式为随机存储,访问方式为顺序访问。

4、查找节点的时间复杂度为O(n),插入、删除节点的时间复杂度为O(1)。

5、链表适用于写操作多,读操作少的场景。

二、单链表

链表是有序的列表,但是它在内存中存储如下:

上图小结:

1、链表是以节点的方式来存储,是链式存储

2、每个节点包含data域,next域:指向下一个节点

3、如图发现链表的各个节点不一定是连续存储

单链表的逻辑结构示意图:

三、关于头结点

链表可以有头节点,也可以没有头节点。

区别在于链表有头节点虽然浪费空间,但易理解,边界好处理,不易出错,代码简单;

相反无头节点,省空间,难理解,边界不易处理,代码稍复杂。

头节点是为了对链表建立、删除、逆向的时候操作更统一,不用专门对第一个元素或最后一个元素进行单独处理。

 

四、为什么要使用链表呢?

1、数组的物理内存上连续的、顺序的空间,如果数组太大或没有连续大小的空间时就需要使用链表了。

2、如果我们要对一组数据进行删除操作时,用数组的话,我们就需要将要删除的那个数据所在的位置后面的所有数据都向前移动一个位置,当我们添加数据时,同样也要让后面的向后挪动一个位置。

如果使用链表的话,就是把那个节点的指针域所指向地址指向下一个节点的地址就可以了。而添加呢,也是类似的指针操作。

当然链表也有劣势,就是查找,如果想要查找某个数据,就必须要从第一个节点开始依次查找。

 那么综上所述,可以知道为什么要用到链表,数组和链表存在的意义了。

那什么又是单向链表?什么又是循环链表?就用一个结构图来表明它们的关系吧。

线性表:一种最简单、常用的数据结构,数据元素之间是一对一的关系。

 五、代码实例

使用带head头的单向链表实现水浒英雄排行管理完成对英雄人物的增删改查操作。

定义英雄实例

package com.atguigu.linkedlist;

public class HeroNode {
	public int no;
	public String name;
	public String nickname;
	public HeroNode next;//指向下一个节点
	
	public HeroNode(int hNo,String hName,String hNickname) {
		this.no = hNo;
		this.name = hName;
		this.nickname = hNickname;
	}

	@Override
	public String toString() {
		return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname+"]";
	}
}

增删改查

package com.atguigu.linkedlist;

public class SingleLinkedList {
	//先初始化一个头节点,头节点不要动,不存放具体数据
	private HeroNode head = new HeroNode(0, "", "");
	//添加节点到单向链表
	//思路,当不考虑编号顺序时
	//1、找到当前链表的最后节点
	//2、将最后节点的next域指向新的节点
	public void add(HeroNode heroNode) {
		//因为head节点不能动,因此我们需要一个辅助变量
		HeroNode temp = head;
		//遍历链表,找到最后
		while(true) {
			//找到链表的最后了
			if(temp.next == null) {
				break;
			}
			//如果没找到,就将temp后移
			temp = temp.next;
		}
		//当退出while循环时temp就指向了链表的最后
		temp.next = heroNode;
	}
	
	//第二种添加英雄方法,根据排名插入指定位置
	//如果排名存在,则添加失败,并给出提示
	public void addByOrder(HeroNode heroNode) {
		//因为头节点不能动,我们仍然通过辅助变量来找到添加的位置
		//因为是单链表,因此我们找的temp是位于添加位置的前一个节点,否者加入失败
		HeroNode temp = head;
		boolean flag = false;//标识添加的编号是否存在,默认为false
		while(true) {
			//说明temp在链表最后
			if(temp.next == null) {
				System.out.println("在链表最后");
				break;
			}
			//位置找到,就在temp的后面插入
			if(temp.next.no > heroNode.no) {
				break;
			}
			//说明编号已经存在
			if(temp.next.no == heroNode.no) {
				flag = true;
				break;
			}
			//后移,遍历当前链表
			temp = temp.next;
		}
		//判断flag的值
		if(flag) {//不能添加,说明编号存在
			System.out.printf("插入英雄的编号%d已经存在,插入失败",heroNode.no);
		}else {
			//插入到链表中,temp的后面
			heroNode.next = temp.next;
			temp.next = heroNode;
		}
	}
	
	//修改节点的信息,根据编号no来修改,no不能修改
	//根据新节点的编号来修改
	public void update(HeroNode newHeroNode) {
		//判断是否为空
		if(head.next == null) {
			System.out.println("链表为空");
			return;
		}
		//找到需要修改的节点,根据no编号
		//定义一个辅助变量
		HeroNode temp = head.next;
		boolean flag = false;//表示是否找到该节点
		while(true) {
			if(temp == null) {
				//表示链表已经遍历结束
				break;
			}
			if(temp.no == newHeroNode.no) {
				flag = true;
				break;
			}
			temp = temp.next;
		}
		//根据flag判断是否找到要修改的节点
		if(flag) {
			temp.name = newHeroNode.name;
			temp.nickname = newHeroNode.nickname;
		}else {
			System.out.printf("没找到编号%d的节点,不能修改\n",temp);
		}
	}
	
	//删除节点
	//思路
	//1、head节点不能动,因此我们需要一个temp辅助节点,找到待删除节点的前一个节点
	//2、说明我们在比较时,是让temp.next.no和需要删除的节点的no进行比较
	public void del(int no) {
		HeroNode temp = head;
		boolean flag = false;//表示是否找到待删除节点的前一个节点
		while(true) {
			if(temp.next == null) {
				System.out.println("已经遍历到最后了");
				break;
			}
			if(temp.next.no == no) {
				//找到了待删除节点的前一个节点temp
				flag = true;
				break;
			}
			temp = temp.next;//temp后移,才能实现遍历
		}
		if(flag){
			temp.next = temp.next.next;
		}else {
			System.out.printf("要删除的节点%d不存在无法删除",no);
		}
	}
	
	//显示链表,通过遍历
	public void list() {
		//先判断链表是否为空
		if(head.next == null) {
			System.out.println("链表为空");
			return;
		}
		//因为头节点不能动,因此需要一个辅助变量来遍历
		HeroNode temp  = head.next;
		while(true) {
			//判断是否到链表最后
			if(temp == null) {
				break;
			}
			//输出节点的信息
			System.out.println(temp);
			//将next后移,一定小心,不然是死循环
			temp = temp.next;
		}
	}
}

 测试类

package com.atguigu.linkedlist;

public class SingleLinkedListDemo {
	public static void main(String[] args) {
		//进行一个测试
		//先创建节点
		HeroNode hero1 = new HeroNode(1,"宋江","及时雨");
		HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟");
		HeroNode hero3 = new HeroNode(3,"吴用","智多星");
		HeroNode hero4 = new HeroNode(4,"公孙胜","入云龙 ");
		
		//创建一个链表
		SingleLinkedList singleLinkedList = new SingleLinkedList();
		//加入
//		singleLinkedList.add(hero1);
//		singleLinkedList.add(hero4);
//		singleLinkedList.add(hero3);
//		singleLinkedList.add(hero2);
		
		//按照编号加入
		singleLinkedList.addByOrder(hero1);
		singleLinkedList.addByOrder(hero4);
		singleLinkedList.addByOrder(hero3);
		singleLinkedList.addByOrder(hero2);
		singleLinkedList.list();
		//测试修改节点的代码
		HeroNode newHeroNode = new HeroNode(2,"小卢","*玉麒麟*");
		singleLinkedList.update(newHeroNode);
		System.out.println("修改之后的链表:");
		singleLinkedList.list();
		
		//删除一个节点
		System.out.println("删除一个节点:");
		singleLinkedList.del(1);
		singleLinkedList.del(2);
		singleLinkedList.del(3);
		singleLinkedList.del(4);
		singleLinkedList.list();
	}

}

六、控制台输出

 

链表详解(单链表、双向链表、链表逆序) 单链表 想了解单链表的一些概念可以看我另一篇博客: 链表基础 单链表结构体定义 //单链表的结构定义 typedef struct LNode { int data; //data存放结点数据域 struct LNode *next; //指向后继结点的指针 }LNode; 单链表的建立 (1)定义单链表的数据结构; (2)读取数据; (3)生成新结点; (4)将数据存入结点的成员变量中; (5)将新结点连接到表头或表尾。 重复(2)~(5)直到输入结束。 //头插法建立单链表 void c 阅读详情

相关推荐

Ubuntu20.04下Pycharm的快速安装与配置指南

本文提供了一份详细的Ubuntu 20.04系统下PyCharm社区版的安装与配置指南。文章重点介绍了通过手动下载.tar.gz压缩包进行安装的灵活方法,并涵盖了系统准备、依赖安装、首次运行、创建快捷方式以及解释器配置等关键步骤,帮助Python开发者快速搭建高效、可控的本地开发环境。

weixin_28831341的博客 379

数据结构之链表

链表是一种物理存储单元上非连续、非顺序的数据结构。前几篇我们讲到的数组也好,基于数组实现的栈和队列也好,都是静态的数据结构,都需要处理容量的问题。而链表是真正的动态数据结构,也是最简单的动态数据结构

zhaojun的博客 1万+

标准恢复二极管整流器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告

报告页数: 150 图表数: 100 报告价格:¥16800 本文研究全球与中国市场标准恢复二极管整流器的发展现状及未来发展趋势,分别从生产和消费的角度分析标准恢复二极管整流器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。 主要生产商包括: Yangzhou Yangjie Vishay Intertechnology Power Semiconductors Inc Nexperia B

Fj69258的博客 5848

数据结构-链表

链表是一种常见的数据结构,由一系列节点构成,每个节点包含当前节点的数据和一个指针(单向链表)或者两个指针(双向链表),链表是一种动态的数据结构,可以动态的增删节点。它的特点是插入与删除数据十分方便,但寻找与读取数据的表现欠佳。

nice66660的博客 1369

【实践指南】Wasserstein距离在电力系统鲁棒优化中的核心应用

本文深入探讨了Wasserstein距离在电力系统分布鲁棒优化中的核心应用。针对风电、光伏出力的不确定性,文章阐述了如何利用Wasserstein距离构建模糊集,将复杂的分布鲁棒优化问题转化为可求解的确定性模型,并提供了从理论到代码实现的完整实践指南,有效平衡了系统运行的经济性与鲁棒性。

weixin_29229261的博客 306

数据中心机房设备标签规范建议

机房的维护工作中,标识管理是极其重要的一部分,从基本的线缆上跳接信息的标识,到设备、机柜标识规范的实施,不同程度的体现了标识管理的重要作用。本规范适用于机房主设备、线缆、机柜(含PDU插排)、仪器仪表、动力配套设备(各类空调、消防设备、配电柜、UPS等设备)、网络口、电源插座口的标签、标识规定。动力设备的设备编号、设备名称、生产厂商及厂商技术支持热线、设备型号、设备序列号、设备使用部门、设备责任人、设备启用时间及设备保修年限、条形码。各类标签、标识可根据设备和机柜的尺寸、大小进行调整。

有地气的强弱电小圈子 3523

数据结构-单链表

链表是数据结构中线性表的一种,其中的每个元素实际上是一个单独的结构体对象,而所有对象都通过每个元素中的指针链接在一起。它是以结构体为节点,将一个结构体看成数据域和指针域两个部分,数据域用于存储数据,指针域用于连接下一个节点。链表中每个结构体对象叫做节点,其中第一个数据节点叫做链表的首元节点;如果第一个节点不用于存储数据,只用于代表链表的起始点,则这个节点称为链表的头节点。

qq_54227351的博客 1999

Android影像系统架构专家面试指南

传音控股招聘影像系统架构专家,要求8年以上开发经验,5年架构设计经验,精通Android Camera开发及性能优化。该职位需负责手机影像软件架构设计、技术选型及跨平台适配,重点解决"快稳省"体验优化。面试评估聚焦三大维度:技术方面考察HAL层架构设计、多帧合成优化等能力;系统开发关注低光降噪等场景的算力平衡;团队管理侧重跨部门协作与项目交付。候选人需展现对CamX-CHI等架构的深入理解,具备量化分析性能指标的能力,并能主导旗舰机影像项目全周期落地。

郑伟强dev的专栏 938

有趣的数据结构算法3——单链表尾插法和头插法的实现

有趣的数据结构算法3——单链表尾插法和头插法的实现什么是单链表头插法的实现尾插法的实现头插法实现代码尾插法实现代码GITHUB下载连接 什么是单链表 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。其与顺...

Bubbliiiing的学习小课堂 4641

PCL RANSAC拟合分割多条直线【2026最新版】

使用RANSAC算法拟合分割多条直线,输出每一条直线的拟合参数到控制台,并保存直线点云到本地文件夹。博客长期更新,本文最新更新时间为:2026年5月24日。

点云侠的博客 7974

12、硬件工程师笔试面试——MOS管(2025版本)

在设计和测试过程中,可以参考相关的EMC测试标准和指南,如CE认证EMC电磁兼容测试介绍 和电磁兼容性(EMC)测试方法与整改指南 ,以及电磁兼容(EMC)的标准与测试内容 ,来确保MOSFET的EMC性能符合行业标准。在高频应用中,MOSFET的开关速度对电路的整体性能至关重要。是一款高电压同步N沟道MOSFET驱动器,具有自举电源电压至114V的能力,宽VCC电压范围,自适应贯通保护功能,以及高达1.4A的峰值顶端栅极上拉电流,适用于分布式电源架构、汽车电源、高密度电源模块和电信系统等应用。

XU157303764的博客 7089

数据结构与算法(3)--- 单链表

本文主要讲述单链表这种数据结构的定义以及它的各种操作,最后说明了一下它与顺序表的区别。

2401_85214846的博客 1336

通过Python实现物联网金橙子自动打标

对于自家公司使用金橙子打标卡时,为了与生产线或者PLC联动等,往往需要对金橙子打标卡进行二次开发,而在二次开发中不得不涉及到MarkEzd.dll这个文件,而这个dll文件网上版本多不说,一般都没法直接使用,最后还不得不花大价钱购买专用库。而本文针对这个问题,涉法通过python来绕过MarkEzd.dll文件,直接进行自动化控制EzCad来实现联动,可应用于实际生产。文章最后拓展一下以物联网的形式,实现手机平台等登录网页,输入想要的印字内容后,远程打印的案例。

lylelo的博客 3365

【数据结构与算法】第3课—数据结构之单链表

链表是在逻辑结构上连续,而在物理结构上不一定连续的存储结构链表由一个一个的节点组成,并且这些节点是在堆上申请空间单链表的每个节点一般有两个变量,一个变量存储数据,另一个变量里面是下一个节点的地址,最后一个节点里面的那个变量存储的是空指针。

weixin_70620792的博客 583

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

数据结构与算法常规操作3——反转一个单链表

写链表代码技巧: 技巧一:理解指针或引用的含义 技巧二:警惕指针丢失和内存泄漏 技巧三:利用哨兵简化实现难度 技巧四:重点留意边界条件处理 技巧五:举例画图,辅助思考 技巧六:多写多练,没有捷径 问题描述:反转一个单链表 代码: class Solution { public ListNode reverseList(ListNode head) { ListNode reverse = null; while (head != null){ ListN

qq_43060870的博客 174

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

数据结构与算法3:链式最基本的表示和实现——单链表

带头指针的单链表:单链表是由表头唯一确定,因此单链表可以用头指针的名字来命名。若头指针名是L,则把链表称为表L。单链表的存储结构注解:这里的data类型统称为ElemType,具体是什么类型,是int还是float,都视具体情况确定。struct Lnode用自己定义自己,这种属于嵌套类型的定义。struct Lnode({}里面的)是什么样的类型呢?是指包括两个成员(ElemType data和struct Lnodenext)的struct Lnode{}这种类型指针去。

uxiang_blog的博客 833

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

数据结构与算法(3)——单链表

链表是一种用于存储数据集合的数据结构 链表的基本操作主要有三个: 1. 遍历链表 2. 向链表中插入一个元素 3. 从链表中删除一个元素

小菜鸟入门 534

3_数据结构原算法_单链表

数据结构与算法_单链表 1、介绍 链表是有序的列表,如下是内存结构: 链表是以节点的方式来存储,是链式存储 每个节点包含 data 域, next 域:指向下一个节点 链表的各个节点不一定是连续存储 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定 单链表(带头节点)如下是逻辑结构: 2、单链表的应用实例 使用带head的链表去存数数据,并实现增、删、改、查 1-1、尾插法 思路: 先创建一个head头节点,作用就是标识单链表的头 后面每天加一个节点,就直接加入到链

renxiaoxu_renxu的博客 120

JAVA数据结构与算法——单链表(3)

单链表节点的修改以及关键代码实现 main函数中: // 修改 HeroNode newHeroNode = new HeroNode(2, "小卢", "玉麒麟~~~~~"); System.out.println("修改后:"); singleLinkedList.update(newHeroNode); singleLinkedList.list(); SingleLinkedList类中加入修改方法: // 修改节点的信息 public void update(He

qq_42120059的博客 193

数据结构与算法分析 3.12 — 单链表转置

题目一: 不含头结点的单链表转置,算法时间复杂度O(N) 代码如下: struct LNode; typedef struct LNode *List; typedef struct LNode *Position; struct LNode { ElementType elem; Position next; }; /* 无头结点单链表转置...

aqjh9999的博客 329

韩顺平 数据结构与算法(3)单链表

3 单链表 1) 链表介绍(Linked List) 链表是以节点的方式来存储 每个节点包含data域,next域(表示指向的下一个节点地址) 如下图:发现链表的各个节点不一定是连续存储 链表分为带头节点的链表和没有头节点的链表,根据实际需求确定 如图: 1. 单链表的实际存储结构 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SnGz1Oip-1634211213137)(C:\Users\三木\AppData\Roaming\Typora\typora-user-im

weixin_52184392的博客 413

数据结构与算法(3)单链表的四道面试题

1. 求单链表中有效节点个数 /** * 方法:获取到单链表的节点个数(如果是带头节点的链表,需求不统计头结点) * * @param head:链表的头结点 * @return:length 有效节点个数 */ public static int getLength(HeroNode head){ if (head.next == null){ return 0; } in

nswzr的博客 205

数据结构与算法(3)单链表的使用

线性表的链式存储结构 线性表的链式存储结构使用任意的存储单元存储线性表的数据元素, 为了连接相邻的元素,数据元素在存储自己的数据信息的同时还需要存储一个指向下一个元素的指针。这两个部分可以区分为数据域和指针域,两者组成结点。 链式存储结构中有单链表,双链表, 和循环链表。主要区别在于指针域的设计上,这篇博客主要讲单链表的使用 单链表 指针域为一个指向后继元素的指针 单链表的链表结构的定义typede

huizhang0110 426
上一篇: 【数据结构与算法 2】循环队列
下一篇: 【程序猿历程】小时候的味道,水浒卡
哪 吒
哪 吒 2022年度博客之星TOP 1 2022年度博客之星TOP 1 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 59万+粉丝 2933原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值