数据结构——链表

article/2025/11/9 12:48:51

数组是常用的数据结构,但是有其局限性:

编译期需要确定元素大小
数组在内存中是连续的,插入或者删除需要移动数组中其他数据
数组适合处理确定长度的,对于插入或者删除不敏感的数据。如果数据是频繁变化的,就需要选择其他数据结构了。本文介绍链表

链表是一种在存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现。链表由一系列的节点组成,节点可以在运行时动态生成,因此链表的长度没有逻辑上的限制,有限制的是堆的大小。在单向链表中。每个节点包含两部分:数据域与指针域。数据域存储数据元素,指针域存储下一结点的指针。

一、单向链表

单向链表是最简单的形式,每个节点是包含两个域:信息域(元素域)和链接域。链接指向链表中的下一个节点,最后一个节点的链接域则指向一个空值。
在这里插入图片描述

head 是头指针,保存首地址,item 存储数据,next 指向下一节点地址。

链表失去了序列的随机读取优点,同时链表增加了指针域,空间开销也较大,但它对存储空间的使用要相对灵活。

1、节点定义

节点数据结构为数据元素item与指针next

class Node(object):"""单链表的结点"""def __init__(self, item):self.item = itemself.next = None

2、链表定义

(1)定义首地址与列表创建
class SingleLinkList(object):"""单链表"""def __init__(self):self._head = None

列表创建:

    link_list = SingleLinkList()# 创建节点node1 = Node(1)node2 = Node(2)# 将节点添加到链表link_list._head = node1# 将第一个节点的next指针指向下一节点node1.next = node2# 访问链表print(link_list._head.item)  # 访问第一个节点数据print(link_list._head.next.item)  # 访问第二个节点数据
(2)链表中的操作方法

is_empty() 链表是否为空
length() 链表长度 ( o(n) )
items() 获取链表数据迭代器
add(item)链表头部添加元素 ( o(1) )
append(item) 链表尾部添加元素 ( o(1) )
insert(pos, item) 指定位置添加元素 ( o(n) )
remove(item) 删除节点 ( o(n) )
find(item) 查找元素是否存在 ( o(n) )

(3)python代码实现
class singleLinkList(object):def __init__(self, Node=None):self._head = Nodedef is_empty(self):return self._head == Nonedef length(self):cur = self._headcnt = 0while cur != None:cnt += 1cur = cur.nextreturn cntdef travel(self):cur = self._headwhile cur != None:print(cur.item, end=' ')cur = cur.nextdef add(self, val):"插入头节点"node = Node(val)node.next = self._headself._head = nodedef append(self, val):"插入尾节点"node = Node(val)if self.is_empty():self._head = nodeelse:cur = self._headwhile cur.next != None:cur = cur.next  # 到当前尾节点cur.next = nodedef insert(self, pos, val):"""在指定位置插入结点"""if pos <= 0:self.add(val)elif pos >= self.length() - 1:self.append(val)  # append 在链表尾部加节点else:node = Node(item)  # 定义节点?cnt = 1cur = self._headpre = Nonewhile cnt != pos:pre = curcur = cur.nextcnt += 1cur =  nodecur.next = pre.nextpre.next = curdef remove(self, val):"移除指定元素"if self.is_empty():print("Empty linklist, Error!")else:cur = self._headpre = Nonewhile cur.item != val:pre = curcur = cur.nextpre.next = cur.nextprint("delete successfully")del curdef search(self, val):"遍历查找某个值"cur = self._headcnt = 1while cur.item != val:cur = cur.nextcnt += 1return cnt  # 返回位置

二、双链表

双向链表在节点中增加一个指针域指向节点的前驱节点。因此每个节点有两个链接:一个指向前一个节点,而另一个链接指向下一个节点。头结点没有前驱结点、尾节点没有后驱结点(或者指向空值)。
在这里插入图片描述

1、节点定义
class Node(object):"""双向链表节点"""def __init__(self, item):# item 存放数据元素self.item = item# next 指向下一个节点self.next = None# pre 指向上一结点self.pre = None
2、双向链表python实现
class BilateralLinkList(object):"""双向链表"""def __init__(self):self._head = Nonedef is_empty(self):"""判断链表是否为空"""return self._head is Nonedef length(self):"""链表长度"""# 初始指针指向headcur = self._headcount = 0# 指针指向None 表示到达尾部while cur is not None:count += 1# 指针下移cur = cur.nextreturn countdef travel(self):"""遍历链表"""# 获取head指针cur = self._head# 循环遍历while cur is not None:# 返回生成器yield cur.item# 指针下移cur = cur.nextdef add(self, item):"""向链表头部添加元素"""node = Node(item)if self.is_empty():# 头部节点指针修改为新节点self._head = nodeelse:# 新结点指针指向原头部节点node.next = self._head# 原头节点pre指针指向新节点self._head.pre = node# head 指向新节点self._head = nodedef append(self, item):"""尾部添加元素"""node = Node(item)if self.is_empty():  # 链表无元素# 头部节点指针修改为新节点self._head = nodeelse:  # 链表有元素# 移动到尾部cur = self._headwhile cur.next is not None:cur = cur.next# 新节点上一级指针指向旧尾部node.pre = cur# 旧尾部指向新节点cur.next = nodedef insert(self, index, item):""" 指定位置插入元素"""if index <= 0:self.add(item)elif index > self.length() - 1:self.append(item)else:node = Node(item)cur = self._headfor i in range(index):cur = cur.next# 新节点的向下指针指向当前节点node.next = cur# 新节点的向上指针指向当前节点的上一节点node.pre = cur.pre# 当前上一节点的向下指针指向nodecur.pre.next = node# 当前节点的向上指针指向新结点cur.pre = nodedef remove(self, item):""" 删除结点 """if self.is_empty():returncur = self._head# 删除元素在第一个节点if cur.item == item:# 只有一个元素if cur.next is None:self._head = Nonereturn Trueelse:# head 指向下一节点self._head = cur.next# 下一节点的向上指针指向Nonecur.next.pre = Nonereturn True# 移动指针查找元素while cur.next is not None:if cur.item == item:# 上一结点向下指针指向下一结点cur.pre.next = cur.next# 下一结点向上指针指向上一结点cur.next.pre = cur.prereturn Truecur = cur.next# 删除元素在最后一个if cur.item == item:# 上一结点向下指针指向Nonecur.pre.next = Nonereturn Truedef find(self, item):"""查找元素是否存在"""return item in self.items()

常用操作:
is_empty(),判断链表是否为空 ,o(n)
length(),返回链表长度,o(n)
travel(),遍历链表,o(n)
add(item),在头部添加一个结点,o(1)
append(item),在尾部添加一个结点,o(1)
insert(position,item),在指定位置添加结点,o(n)
remove(item),删除值为item的第一个结点,o(n)
search(item),查找结点是否存在,o(n)

三、单向循环链表

当单向链表的尾节点不指向None,而是指向头结点的时候,那么就构成了一个单向循环链表。

单循环链表中一些操作的时间复杂度:

is_empty(),判断链表是否为空 ,o(n)
length(),返回链表长度,o(n)
travel(),遍历链表,o(n)
add(item),在头部添加一个结点,o(n)
append(item),在尾部添加一个结点,o(1)
insert(position,item),在指定位置添加结点,o(n)
remove(item),删除值为item的第一个结点,o(n)
search(item),查找结点是否存在,o(n)

class Node(object):"""节点"""def __init__(self, item):self.item = itemself.next = Noneclass SinCycLinkedlist(object):"""单向循环链表"""def __init__(self):self._head = Nonedef is_empty(self):"""判断链表是否为空"""return self._head == Nonedef length(self):"""返回链表的长度"""# 如果链表为空,返回长度0if self.is_empty():return 0count = 1cur = self._headwhile cur.next != self._head:count += 1cur = cur.nextreturn countdef travel(self):"""遍历链表"""if self.is_empty():returncur = self._headprint cur.item,while cur.next != self._head:cur = cur.nextprint cur.item,print ""def add(self, item):"""头部添加节点"""node = Node(item)if self.is_empty():self._head = nodenode.next = self._headelse:#添加的节点指向_headnode.next = self._head# 移到链表尾部,将尾部节点的next指向nodecur = self._headwhile cur.next != self._head:cur = cur.nextcur.next = node#_head指向添加node的self._head = nodedef append(self, item):"""尾部添加节点"""node = Node(item)if self.is_empty():self._head = nodenode.next = self._headelse:# 移到链表尾部cur = self._headwhile cur.next != self._head:cur = cur.next# 将尾节点指向nodecur.next = node# 将node指向头节点_headnode.next = self._headdef insert(self, pos, item):"""在指定位置添加节点"""if pos <= 0:self.add(item)elif pos > (self.length()-1):self.append(item)else:node = Node(item)cur = self._headcount = 0# 移动到指定位置的前一个位置while count < (pos-1):count += 1cur = cur.nextnode.next = cur.nextcur.next = nodedef remove(self, item):"""删除一个节点"""# 若链表为空,则直接返回if self.is_empty():return# 将cur指向头节点cur = self._headpre = None# 若头节点的元素就是要查找的元素itemif cur.item == item:# 如果链表不止一个节点if cur.next != self._head:# 先找到尾节点,将尾节点的next指向第二个节点while cur.next != self._head:cur = cur.next# cur指向了尾节点cur.next = self._head.nextself._head = self._head.nextelse:# 链表只有一个节点self._head = Noneelse:pre = self._head# 第一个节点不是要删除的while cur.next != self._head:# 找到了要删除的元素if cur.item == item:# 删除pre.next = cur.nextreturnelse:pre = curcur = cur.next# cur 指向尾节点if cur.item == item:# 尾部删除pre.next = cur.nextdef search(self, item):"""查找节点是否存在"""if self.is_empty():return Falsecur = self._headif cur.item == item:return Truewhile cur.next != self._head:cur = cur.nextif cur.item == item:return Truereturn False

原文参考:
https://zhuanlan.zhihu.com/p/52878334
https://blog.csdn.net/qq_38851184/article/details/105750984


http://chatgpt.dhexx.cn/article/jmrM3mZd.shtml

相关文章

数据结构-链表

链表 一、介绍1、单链表1、单链表结构体&#xff1a;2、单链表头插法&#xff1a;3、单链表尾插法&#xff1a; 二、例题1、双指针&#xff08;获取倒数第K个元素、获取中间位置的元素、判断链表是否存在环、判断环的长度、查找第一个公共节点、回文链表&#xff09;1、 判断链…

C语言数据结构、十字链表的分析及实现

目录 前言 一、什么是十字链表 二、认识十字链表 1.十字链表的组成 2.顶点和弧的连接 三、代码逻辑实现 1.出度 2.入度 总结 前言 无论是什么程序都要和数据打交道&#xff0c;一个好的程序员会选择更优的数据结构来更好的解决问题&#xff0c;因此数据结构的重要性不言…

JS 数据结构:链表

单链表 每个节点中只包含一个指针域的链表称为单链表。 头结点—其指针域指向表中第一个结点的指针&#xff08;头结点不是必须的&#xff0c;只是习惯上加上头结点&#xff0c;而头结点的数据域一般记录的是该链表的相关数据&#xff0c;如&#xff1a;链表长度&#xff09;…

数据结构中链表和列表的区别

顺序表和链表由于存储结构上的差异&#xff0c;导致它们具有不同的特点&#xff0c;适用于不同的场景。通过系统地学习顺序 表和链表我们知道&#xff0c;虽然它们同属于线性表&#xff0c;但数据的存储结构有本质的不同。 • 顺序表存储数据&#xff0c;需预先申请一整块足够…

数据结构(六)——循环链表

一、循序链表简介 1、循环链表的定义 循环链表的任意元素都有一个前驱和一个后继&#xff0c;所有数据元素在关系上构成逻辑上的环。 循环链表是一种特殊的单链表&#xff0c;尾结点的指针指向首结点的地址。 循环链表的逻辑关系图如下&#xff1a; 2、循环链表的设计实现 …

数据结构-使用链表实现栈

目录结构 Stack接口 package LinkedListStack;public interface Stack<E> {int getSize();boolean isEmpty();void push(E e); //向栈中添加元素E pop();//向栈中取出元素E peek();//查看栈顶的元素 }LinkedList类 package LinkedListStack;public class LinkedList<…

数据结构 | 链表的实现

目录 单链表双链表数组结构和链式结构的对比 线性表中&#xff0c;除了顺序表这一重要的结构&#xff0c;还有链式结构&#xff0c;而这也是我们常说的链表。 一般是通过定义结构体(类)的方式来表示链表的每一个结点。一般而言&#xff0c;链表的结点都会有数据域和地址域。数据…

Java数据结构之链表

目录 一.单链表 1.单链表的介绍和内存布局 2.单链表的添加和遍历 3.单链表的插入 4.单链表的删除 二.双向链表 1.添加节点 2.遍历节点 3.插入节点 4.删除结点 5.测试 三.单向环形链表 1.问题的引出 ​编辑 2.构建环形链表 1.创建结点 3.测试 3.约瑟夫问题代码的…

c++数据结构:链表

链表是一种物理存储单元上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点&#xff08;链表中每一个元素称为结点&#xff09;组成&#xff0c;结点可以在运行时动态生成。每个结点包括两个部分&#xff1a;一个是…

java数据结构-链表详解

文章目录 1.数据结构-链表详解1.1单链表1.1.1单链表节点的尾部添加1.1.2单链表节点的自动排序添加1.1.3单链表节点的修改1.1.4单链表节点的删除 1.2单链表面试题1.2.1单链表的有效节点个数1.2.2单链表倒数第k个结点1.2.3单链表反转1.2.4单链表逆序打印 1.3双向链表1.3.1双向链表…

C语言数据结构链表(图文)

目录 一、链表的简单理解与引入 1.1 链表的引入 1.2 节点的理解 1.3 链表的分类 二、常用链表功能的实现 2.1 首先是节点的定义&#xff0c; 2.2 节点的创建 2.3 单链表的尾插 2.4 单链表的尾删 2.5 单链表的头插 2.6 链表的头删 2.7 单…

【数据结构】链表的学习总结

目录 1.链表的概念2.链表的结构1️⃣链表中单个结点的结构2️⃣链表的整体结构 3.链表的分类4.链表的实现1️⃣单向无头非循环2️⃣双向带头循环 1.链表的概念 链表&#xff0c;是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表 中的指针…

C++数据结构之链表(详解)

主要参考文章地址 01.链表基础知识 | 算法通关手册 (itcharge.cn)&#xff09; 本次内容是对链表的总结&#xff0c;可以看了上面的文章之后。 在看我下面的内容&#xff0c;做一个简短的复习&#xff0c;且本内容的代码均用C实现&#xff0c;而参考资料的代码则为python。 …

[数据结构]链表之单链表(详解)

文章目录 [数据结构]链表之单链表前言1.链表1.1链表的概念及结构1.2单链表与顺序表的区别与优缺点1.3八种链表类型、单向带头循环链表单向带头非循环链表单向不带头循环链表单向不带头非循环链表双向带头循环链表双向带头非循环链表双向不带头循环链表双向不带头非循环链表 2.单…

【数据结构与算法】详解什么是链表,并用代码手动实现一个链表结构

本系列文章【数据结构与算法】所有完整代码已上传 github&#xff0c;想要完整代码的小伙伴可以直接去那获取&#xff0c;可以的话欢迎点个Star哦~下面放上跳转链接 https://github.com/Lpyexplore/structureAndAlgorithm-JS 本文将来讲解一下一种常见的线性数据结构—链表&a…

数据结构-链表篇

数据结构中数组和链表是是使用频率最高的基础数据结构。数组作为数据存储结构有一定的缺陷。在无序数组中&#xff0c;搜索性能差&#xff0c;在有序数组中&#xff0c;插入效率又很低&#xff0c;而且这两种数组的删除效率都很低&#xff0c;并且数组在创建后&#xff0c;其大…

数据结构之——链表

目录 一、链表的概念及结构 二、单链表的实现&#xff08;无头单向非循环链表&#xff09; 1.单链表节点定义 2.单链表的接口实现 &#xff08;1&#xff09;动态申请一个节点 &#xff08;2&#xff09;单链表打印 &#xff08;3&#xff09;单链表的销毁 &#xff0…

【数据结构】链表

单链表 这张图是我们待会要实现的功能&#xff0c;我会尽可能的将每一步都说的很详细&#xff0c;方便理解。 链表的概念及结构 概念&#xff1a;链表是一种 物理存储结构上非连续 、非顺序的存储结构&#xff0c;数据元素的 逻辑顺序 是通过链表中的 指针链 接 次序实现的 。…

数据结构之链表

目录 一、链表的特点 二、虚拟头结点 三、链表的实现 1、定义LinkedList 2、 构造方法 3、基本方法 4、添加元素 5、查找元素 6、修改元素 7、删除元素 链表是一种物理存储单元上非连续、非顺序的数据结构。前几篇我们讲到的数组也好&#xff0c;基于数组实现的栈…

[数据结构] 链表(图文超详解讲解)

文章目录 一、链表是什么&#xff1f;二、链表 1.链表的结构2.链表方法的代码实现总结 一、链表是什么&#xff1f; 链表是一种物理存储结构上非连续存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。 二、链表 1.链表的结构 链表的结构如图: 链…