Python实现单向链表

关于链表的介绍,请参考:https://blog.csdn.net/weixin_43790276/article/details/104033254

本篇文章使用 Python 来实现一个单向链表。

一、定义一个创建节点的类

链表是由一个个的节点组成的,在创建链表之前,要先创建节点,然后把节点“串”到链表上。在同一个链表中,每个节点的结构都相同,只是节点中保存的数据不同和引用不同,所以提前声明一个创建节点的类,需要创建节点时实例化即可。

# coding=utf-8
class Node(object):def __init__(self, data):self.data = dataself.next = None

单向链表的节点包含两个域,一个信息域(元素域)和一个链接域(引用域)。在实例化一个节点时,需要传入该节点中保存的数据,保存到信息域中,链接域默认为空,当对节点进行“链接”操作时,再设置具体的链接域。

二、定义一个单向链表类

对于单向链表,在没有将节点“链接”上去时,这个链表里没有节点和数据。实例化一个单向链表时,这个单向链表是一个空链表,把节点依次“链接”上去后,链表中才有节点和数据。

在链表中,要找到链表的某个节点,需要从链表的头节点开始,依次寻找,所以在实例化一个链表时,必须定义好链表的“头”,当加入头节点时,将链表的“头”指向头节点。

定义一个单向链表类 SingleLinkList,初始化一个单向链表时,链表的“头”指向空值,默认为空链表。

class SingleLinkList(object):def __init__(self):self.__head = None

三、实现单向链表的展示功能

    def is_empty(self):return not self.__headdef show(self):if self.is_empty():print('空链表')returncur = self.__headwhile cur is not None:if cur.next is not None:print(cur.data, end=' → ')else:print(cur.data)cur = cur.next

先实现判断单向链表是否为空的方法 is_empty() ,实例化单向链表时,默认是空的,单向链表的头指向为空。所以,如果单向链表的头指向为空(对应布尔值False), is_empty() 的值就为 True ,反之。

展示链表中的数据,就是将链表中所有的数据依次打印输出。链表不像顺序表有“索引”,链表只能从头节点开始依次往下找,直到尾节点。所以链表不能使用 for 循环进行遍历,只能使用 while 循环进行遍历,并使用一个游标 cur 来记录当前所处的节点,通过游标 cur 向链接域指向的节点(下一个节点)移动来遍历,当链接域为空(尾节点)时停止。

实现 show() 方法时,为了更形象地展示链表中每个节点的关系,我在相邻两个节点之间使用右箭头连接(空链表无效果)。

if __name__ == '__main__':s = SingleLinkList()print("is_empty: ", s.is_empty())s.show()

运行结果:

is_empty:  True
空链表

四、实现单向链表中添加数据的功能

    def add(self, data):node = Node(data)node.next = self.__headself.__head = nodedef append(self, data):if self.is_empty():self.add(data)returncur = self.__headwhile cur.next is not None:cur = cur.nextnode = Node(data)cur.next = nodedef length(self):length = 0cur = self.__headwhile cur is not None:length += 1cur = cur.nextreturn lengthdef insert(self, index, data):if index <= 0:self.add(data)returnif index > self.length() - 1:self.append(data)returncur = self.__headfor i in range(index-1):cur = cur.nextnode = Node(data)node.next = cur.nextcur.next = node

添加数据到单向链表中,可以从头部添加、从尾部添加或从指定位置添加。

无论将数据添加到链表的哪个位置,都要先创建一个新节点,新节点里存放对应的数据,然后将新节点添加到指定的位置。

add(data):从头部添加时,链表原来的头节点会成为第二个节点,新节点成为头节点,所以先将新节点的链接域指向原来的头节点,然后将链表的头指向新节点。如果原来的链表为空,则链表的头原来是指向空,所以直接将链表的头指向新节点即可,代码不用变。

append(data):从尾部添加时,先找到链表的尾节点,然后将尾节点的链接域指向新节点。如果原来的链表为空,则链表没有尾节点,这时候与从头部添加一样,直接调用即可。

insert(index, data):在指定位置添加数据时,要使用一个游标 cur 来找到此位置的前一个节点,将新节点的链接域指向指定位置原来的节点,然后将游标记录的节点(指定位置的前一个节点)的链接域指向新节点,这样就成功将新节点插入到了指定位置。

如果指定的位置是负数或超过了链表最大长度,则需要特殊处理,上面的处理是负数在头部添加,超过最大长度在尾部添加。也可以直接抛出 IndexError ,这个可以自己按需选择。

同时,上面实现了获取单向链表长度的方法 length(),返回链表当前的节点个数。

    s.add(1)s.add(10)s.append(2)s.append(3)s.append(4)s.show()s.insert(1, 20)s.show()print("链表长度:", s.length())

运行结果:

10 → 1 → 2 → 3 → 4
10 → 20 → 1 → 2 → 3 → 4
链表长度: 6

五、实现单向链表的查询和修改功能

    def is_exist(self, value):cur = self.__headwhile cur is not None:if cur.data == value:return Truecur = cur.nextreturn Falsedef index(self, value):index = 0cur = self.__headwhile cur is not None:if cur.data == value:return indexcur = cur.nextindex += 1return -1def setitem(self, index, value):if index < 0:raise IndexErrorif index > self.length() - 1:raise IndexErrorcur = self.__headfor i in range(index):cur = cur.nextcur.data = value

is_exist(value):判断一个数据是否存在链表中,遍历单向链表的每个节点,如果节点的数据值与目标值相等,则说明链表中存在目标值。

index(value):返回一个数据在链表中的第几个节点,与判断是否存在的实现方式一样,这里返回的是数据处于第几个节点中,如果链表中没有这个数据,则返回-1。

setitem(index, value):修改指定位置的节点的数据,先根据给定的值,找到链表中该位置的节点,然后修改节点中的数据。如果数值小于零或大于链表长度,抛出 IndexError 。

    print(s.is_exist(200))print(s.index(20))s.setitem(2, 30)s.show()

运行结果:

False
1
10 → 20 → 30 → 2 → 3 → 4

六、实现单向链表的删除功能

    def remove(self, index):if index < 0:raise IndexErrorif index > self.length() - 1:raise IndexErrorcur = self.__headprev = Nonefor i in range(index):prev = curcur = cur.nextif cur == self.__head:self.__head = self.__head.nextreturnprev.next = cur.nextdef delete(self, value):cur = self.__headprev = Nonewhile cur is not None:if cur.data == value:if cur == self.__head:self.__head = self.__head.nextreturnprev.next = cur.nextreturnprev = curcur = cur.nextdef delete_all(self, value):cur = self.__headprev = Nonewhile cur is not None:if cur.data == value:if cur == self.__head:self.__head = self.__head.nextself.delete_all(value)else:prev.next = cur.nextself.delete_all(value)prev = curcur = cur.next

remove(index):删除指定位置的节点,通过游标 cur 找到节点,将该节点删除后,要保证链表不断开,就要将该位置的前一个节点的链接域指向该位置的后一个节点,所以再使用一个游标 prev 来记录当前节点的前一个节点。如果删除的是头节点,则直接将链表的头指向第二个节点。如果指定的位置小于零或超过链表长度,则抛出 IndexError 。

delete(value):删除指定值的节点,先遍历链表,找到对应值的节点,然后将该节点的前一个节点的链接域指向该节点的后一个节点,这里也是使用两个游标来记录节点和前一个节点的位置。如果删除的是头节点,则直接将链表的头指向第二个节点。

使用这个方法,如果链表中有多个满足条件的节点,只会删除最前面的一个节点。

delete_all(value):删除数据等于指定值的所有节点,如果链表中有多个节点的数据与目标值相等,删除第一个节点后,链表的长度发生了改变,继续遍历和删除节点,会出现删除不完全甚至程序出错的情况。所以在删除第一个节点之后,递归调用自身,这样重新遍历时使用的是新的链表长度,不会出现漏删或错误。

    s.remove(3)s.show()s.delete(4)s.show()s.add(4)s.insert(3, 4)s.insert(3, 4)s.append(4)s.append(4)s.show()s.delete_all(4)s.show()

运行结果:

10 → 20 → 30 → 3 → 4
10 → 20 → 30 → 3
4 → 10 → 20 → 4 → 4 → 30 → 3 → 4 → 4
10 → 20 → 30 → 3

以上就是用 Python 实现的单向链表及单向链表的一些简单操作方法。

Python实现单向链表相关推荐

  1. 用Python实现单向链表

    单向链表 单向链表也叫单链表,是链表中最简单的⼀种形式,它的每个节点包含两个域,⼀个信息域(元素域)和⼀个链接域.这个链接指向链表中的下⼀个节点,⽽最后⼀个节点的链接域则指向⼀个空值. 表元素域ele ...

  2. python数据结构与算法:单向链表

    单链表:python实现及其对应的 增删查检 操作 ##################### P4.1-P4.8 单向链表 ########################### #coding:u ...

  3. node 获取表单数据 为空_数据结构与算法(python)单向链表篇

    链表 数据表的构建需要预先知道数据的大小来申请连续的存储空间, 而在进行扩充的时候又需要进行数据的搬迁, 使用起来不是很灵活. 链表结构可以充分利用计算机内存空间, 实现灵活的内存动态管理. 简单来说 ...

  4. python 判断div 之间的内容是否为空_python实现单向链表数据结构及其基本方法

    顺序表和链表作为线性表的典型结构,上一篇已经说了顺序表在python中的典型应用:list和tuple,<顺序表数据结构在python中的应用>,今天来实现链表的基本结构之一:单向链表. ...

  5. python创建链表实例_python数据结构链表之单向链表(实例讲解)

    python数据结构链表之单向链表(实例讲解) 单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后 ...

  6. 单向链表-python

    文章目录 为什么需要链表? 定义 单向链表 链表节点实现 单链表的操作 单链表基础功能的实现 在头部添加元素 在尾部添加元素 在指定位置插入元素 删除节点 查找节点是否存在 全部程序 单项循环链表 基 ...

  7. 算法—详细讲解单向链表的实现(python)

    链表 链表是一种物理存储单元上非连续.非顺序的存储结构 数据元素的逻辑顺序通过链表中的指针链接次序实现 链表由一系列节点组成,节点可以在运行时动态生成 每个节点包含两个部分:存储数据元素的数据区.存储 ...

  8. python单向链表和双向链表的图示代码说明

    图示说明: 单向链表: insert. remove. update.pop方法 class Node:def __init__(self, data):self.data = dataself.ne ...

  9. python 单向链表

    1 # -*- coding: utf-8 -*- 2 # @author: Tele 3 # @Time : 2019/04/22 下午 3:17 4 # 单向链表的实现 5 # 每个节点包含两部分 ...

最新文章

  1. 天池 在线编程 扫雷(BFS)
  2. 试玩C++ 操作页面控件
  3. dg oracle 切换模式_Oracle数据库 DGbroker三种保护模式的切换
  4. SCUT - 243 - 宝华复习 - 二分 - 桶计数
  5. python有多少种语法_这20个常规Python语法你都搞明白了吗?
  6. 如果外卖APP想窃听我,有几个骚操作?
  7. os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' 无效
  8. javascript对数组的操作
  9. 一篇个人认为对RNN写的比较好的文章
  10. PSFTP 常用命令
  11. ae效果英文版翻译对照表_AE CS6 最全特效中英翻译
  12. 数据处理-倾斜摄影OSGB合并根节点
  13. Ubuntu 安装QT
  14. 转载-极化码系列(2)-极化码的编码原理
  15. 路由器忘记密码的解决办法
  16. 【Windows】安装NVIDIA驱动 / 更新驱动
  17. linux查看云锁密码命令,Linux安装云锁
  18. OSChina 周五乱弹 ——给网戒中心打电话,结果……
  19. Git 修改历史 commit 提交信息
  20. 双目立体视觉(3)- ZED2 ROS Melodic 发布RGB图像及深度信息

热门文章

  1. Mysql慢查询操作梳理
  2. codeforces679C Bear and Square Grid(dfs优化)
  3. Spring-boot配置JedisShardInfo
  4. oracle的redo与undio
  5. 采用rsync实现两台solaris服务之间的文件同步
  6. 【ASP.NET】基础补习之验证控件
  7. 你不知道的Chrome调试技巧
  8. 搭建个人博客,还有比这更快的?
  9. Java服务,内存OOM问题如何快速定位?
  10. Linux内核参数(如kernel.shmmax)及Oracle相关参数调整(如SGA_MAX_SIZE)