Python3 实现单向链表

链表定义与简介

  • 定义:链表与顺序表(Python中列表)性质相反,链表是物理单元上非顺序的、非连续的,在逻辑顺序上其数据元素是通过指针实现的,组成链表的每一个元素也可以叫做链表的节点,节点可以在运行时动态生成

    单向链表中所有的元素也可以称之为节点,每个节点包含两个区域,如上图item区域称为数据域,next区域为指针域,单向链表中尾节点的判断只需判断该节点的指针(next)是否指向空即可。

链表(Linked list)与顺序表(Sequence list)的主要差异

  • 顺序表的内存地址是连续的,其数据元素有对应唯一的索引,搜索时非常方便,但进行元素插入时较麻烦,每次插入元素,其后所有元素都要移动一位。
  • 而链表内存地址是非连续、非顺序的,逻辑顺序由指针实现,在插入元素时只需将指定位置的前一个元素的指针断开,并指向要插入的元素的节点,然后插入的元素指针再指向下一个节点即可,但是在查询元素时,需要从头结点开始一个一个遍历寻找。

由于链表不是必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

定义单链表

# 定义节点
class Node:def __init__(self, item):self.item = itemself.next = None# 定义链表
class SingleLinkList:def __init__(self):self._head = Noneif __name__ == '__main__':# 创建链表link_list = SingleLinkList()# 创建结点node1 = Node(1)node2 = Node(2)# 将结点添加到链表link_list._head = node1# 将第一个结点的next指针指向下一结点node1.next = node2# 访问链表print("head", link_list._head)  # 访问第一个结点数据print(link_list._head.item)  # 访问第一个结点数据print(link_list._head.next.item)  # 访问第二个结点数据

一个简单的链表,没有增删改查等功能,操作十分不便

接下来对其,进行一部分常用功能实现:

  1. 清空元素clear(),断开头结点的指针,长度为0
  2. 展示元素的值show_items()
  3. 获取元素get_value_by_index(),以偏移量获取元素的值,超出偏移量会报错IndexErorr,可以是负偏移
  4. 判断链表是否为空is_empty()
  5. 返回链表长度length()
  6. 在指定位置插入insert(),当超过实际长度,在最后插入;当为负数倒序选择插入,负数的绝对值大于实际长度则在最前面插入
  7. 在末尾追加元素append()
  8. 指定偏移量移除元素remove(),超过偏移量,抛出IndexErorr,可以使用负偏移
  9. 判断一个元素是否存在于链表is_exist(),存在返回True,否则返回False
  10. 返回元素的偏移indexOf()

代码实现

class Node:"""The nodes of single linked list"""def __init__(self, item):self.item = itemself.next = Noneclass SingleLinkedList:def __init__(self):"""Initialize the head and the length of single linked list"""self.head = Nonedef clear(self):"""CLear a linked list"""self.head = Nonedef show_items(self):"""Show all the elements of linked list"""if self.is_empty():return Nonecur = self.headwhile cur.next:yield cur.itemcur = cur.nextyield cur.itemdef get_value_by_index(self, index):"""Get a value by index"""node = self.headindex = self.length()+index if index < 0 else indexif index < 0:raise IndexError('index out of range')try:for i in range(index):node = node.nextreturn node.itemexcept AttributeError as e:raise IndexError('index out of range')def is_empty(self):"""Judge if a linked list is empty"""return self.head is Nonedef length(self):"""Return the elements number of a linked list"""cur = self.headif not cur:return 0count = 1while cur.next:count += 1cur = cur.nextreturn countdef insert(self, index, item):"""Insert an element before the given index of a node"""node = Node(item)length = self.length()# Empty list, append directlyif not self.head:self.append(item)if index < 0 and (index + length) >= 0:index += length# index>0if index > 0:cur = self.headwhile cur.next:if index <= 1:breakcur = cur.nextindex -= 1node.next = cur.nextcur.next = nodeelif index == 0 or index + length < 0:temp = self.headnode.next = tempself.head = nodedef append(self, item):"""Append elements to the end of a linked list"""node = Node(item)if self.is_empty():self.head = nodeelse:cur = self.headwhile cur.next:cur = cur.nextcur.next = nodedef remove(self, index):"""Remove an element by index"""if not -self.length() - 1 < index < self.length():raise IndexError('remove index out of range')if index < 0:index += self.length()print(f"index", index)if index == 0:print("Get into ")self.head = self.head.nextelse:cur = self.headpre = curwhile index > 0:pre = curcur = cur.nextindex -= 1pre.next = cur.nextdef is_exist(self, item):"""Judge if an element in linked-list"""return item in self.show_items()def indexOf(self, item):"""Return a given item's index where is the first appearance in the list"""return list(self.show_items()).index(item)

验证功能

if __name__ == '__main__':SLL = SingleLinkedList()print(f"If the linked list is empty?: {SLL.is_empty()}")# Append elements to the endfor i in range(5):SLL.append(i)print(f"Show all items:{list(SLL.show_items())}")print(f"The length of {SLL.__class__.__name__}: {SLL.length()}")# _index>0_index, _item = 9, 11SLL.insert(_index, _item)print(f"Insert {_item} before linked list[{_index}]: {list(SLL.show_items())}")# _index=0_index, _item = 0, 22SLL.insert(_index, _item)print(f"Insert {_item} before linked list[{_index}]: {list(SLL.show_items())}")# _index<0 and length+_index>0_index, _item = -3, 33SLL.insert(_index, _item)print(f"Insert {_item} before linked list[{_index}]: {list(SLL.show_items())}")# _index<0 and length+_index<0_index, _item = -21, 44SLL.insert(_index, _item)print(f"Insert {_item} before linked list[{_index}]: {list(SLL.show_items())}")_index = -5SLL.remove(_index)print(f"Remove an element by index[{_index}]: {list(SLL.show_items())}")# Get a value by index, if index out of range, throw a IndexError_index = 3print(f"Get a value by index[{_index}], its value: {SLL.get_value_by_index(3)}")_item = 44print(f"If item:[{_item}] in linked list {SLL.__class__.__name__}? {SLL.is_exist(_item)} ")# CLear a linked listprint(f"The linked list has been cleared: {SLL.__class__.__name__}: {SLL.clear()}")print(f"The length of {SLL.__class__.__name__}: {SLL.length()}")

结果

If the linked list is empty?: True
Show all items:[0, 1, 2, 3, 4]
The length of SingleLinkedList: 5
Insert 11 before linked list[9]: [0, 1, 2, 3, 4, 11]
Insert 22 before linked list[0]: [22, 0, 1, 2, 3, 4, 11]
Insert 33 before linked list[-3]: [22, 0, 1, 2, 33, 3, 4, 11]
Insert 44 before linked list[-21]: [44, 22, 0, 1, 2, 33, 3, 4, 11]
Remove an element by index[-5]: [44, 22, 0, 1, 33, 3, 4, 11]
Get a value by index[3], its value: 1
If item:[44] in linked list SingleLinkedList? True
The linked list has been cleared: SingleLinkedList: None
The length of SingleLinkedList: 0

数据结构链表之单向链表:Python3 实现单向链表——1相关推荐

  1. 基础数据结构【二】————动态数组,单向链表及链表的反转

    DEMO1:     动态分配变量(链表,而静态数组是线性表,意味着动态数组访问和遍历复杂度为O(n),而插入和删除复杂度为O(1),而静态数组线性表则完全相反) int* intptr = new ...

  2. c语言单向链表经典,C语言基础 - 实现单向链表

    写在前面 弄了下个人站...防止内容再次被锁定...所有东西都在这里面 welcome~ 个人博客 回归C基础 实现一个单向链表,并有逆序功能 (大学数据结构经常是这么入门的) //定义单链表结构体 ...

  3. neo4j 查询同一节点的两个上级_链表的魅力:两个单向链表的第一个交点

    最近听了左神的算法课,对一些常用数据结构以及算法改进的思路有了更深的理解,特此总结,不定期更新算法题目以及答案总结!笔者使用C++进行算法重现!虽然左神使用的是JAVA,但他自己也说了,算法与语言无关 ...

  4. C语言实现链表【一】(无头单向非循环链表)

    无头单向非循环链表 看到这个标题,是不是有小伙伴已经懵了呢? 只学过链表,怎么还有个无头和有头呢?怎么还有个循环和非循环呢?怎么还有个单向和双向呢?一连串的疑问... 其实这些都是链表的表示形式,只不 ...

  5. 【了解链表的适用场景;掌握单向链表、双向链表的使用】(学习笔记18--链表)

    目录 单向链表 双向链表 链表中的节点和火车的车厢一样,是一个连着一个的,通常将当前节点的前一个或上一个节点称为它的前驱节点,将后一个或者下一个节点称之为它的后继节点.链表中的第一个节点被称为头节点, ...

  6. 【链表】如何判断两个单向链表是否有相交,并找出交点

    判断两个链表是否相交:(假设两个链表都没有环) 1.判断第一个链表的每个节点是否在第二个链表中 2.把第二个链表连接到第一个后面,判断得到的链表是否有环,有环则相交 3.先遍历第一个链表,记住最后一个 ...

  7. c语言单向链表插入字符串,C语言之单向链表

    1,单向链简洁. 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始:链表是使用指针进行构造的列表:又称为结点列表,因为链表是由一个个结点组装起来的: ...

  8. 数据结构链表之双向链表:Python3 实现双向链表——2

    Python3 实现双向链表 双向链表 定义:双向链表是链表中的一种,双向链表也叫双链表,它由多个节点组成,每个节点由一个数据域和两个指针域组成,一个指针指向前驱元素,一个指向后继元素 双向链表一般用 ...

  9. JAVA day16、17 数据结构(栈、队列、数组、链表、红黑树)

    一.什么叫数据结构? 数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带"结构"的数据元素的集合."结构"就是指数据元素之间存在的关系,分为逻辑结构 ...

最新文章

  1. 磁盘修复工具TestDisk
  2. golang time 时间 加减法
  3. python进制转换内置函数_python数学运算、逻辑运算和进制转化相关的 内置函数...
  4. Spring MVC中Session的正确用法之我见02
  5. 还在为周会发愁?你需要这13篇最新论文 | 本周值得读
  6. 计算机常用英语(2)
  7. C++程序设计语言编程风格演变史
  8. mysql 结果集 超大_使用MySQL流式传输大型结果集
  9. jQuery的实现,去掉传入html代码两端的空格:
  10. 帝国cms文章内容tags关键词设置调用方法以及tags静态化
  11. 关于appium中的Multiaction的用法
  12. Bayer Pattern
  13. Python爬虫16-Scrapy爬取阳光政务平台信息
  14. 用python一条命令解决多个ts转换成MP4(就一条),备用两选一
  15. 使用VSCode 进行IRIS 开发
  16. 关于生僻字乱码的问题
  17. CompletableFuture学习
  18. win10计算机无法复制文件,Win10系统禁止U盘拷贝文件的方法【图文】
  19. OneKeyGhost工具进行备份还原windows操作系统
  20. CSS特效 操作方法

热门文章

  1. Android应用开发——service连接泄露异常:android.app.ServiceConnectionLeaked: that was originally bound here
  2. 学成在线--12.Spring整合RibbitMQ
  3. Windows中安装MongoDB以及studio3t
  4. 计算机科学与技术考研课程安排,计算机科学与技术(0812)硕士研究生培养方案(一)...
  5. 如何做相册_手机里的照片太多,不得已只能删除?那就试试制作电子相册吧
  6. 汇编指令的学习4——ldm/stm指令、栈的处理
  7. 破坏计算机系统既遂的标准,破坏计算机信息系统罪的量刑标准是什么
  8. Cucumber+Rest Assured快速搭建api自动化测试平台
  9. 前端开源项目周报0307
  10. centos安装python3.5和pip