链表是节点的集合。第一个节点(Node)一般被称为Head。最后一个节点的Next属性必须指向 None ,表明是链表的结尾。

在大多数编程语言中,链表和数组在内存中的存储方式存在明显差异。数组要求内存空间是连续的,链表可以不连续。

然而,在 Python 中,list是动态数组。所以在Python中列表和链表的内存使用非常相似。

链表和数组在以下的操作中也有本质区别:

1.插入元素:数组中插入元素时,插入位置之后的所有元素都需要往后移动一位,所以数组中插入元素最坏时间复杂度是 O(n)链表可以达到 O(1) 的时间复杂度。

2. 删除元素:数组需要将删除位置之后的元素全部往前移动一位,最坏时间复杂度是 O(n),链表可以达到 O(1) 的时间复杂度。

3.随机访问元素:数组可以通过下标直接访问元素,时间复杂度为O(1)。链表需要从头结点开始遍历,时间复杂度为O(n)。

4.获取长度: 数组获取长度的时间复杂度为O(1),链表获取长度也只能从头开始遍历,时间复杂度为O(n)。
实现链表

class LinkedList:def __init__(self):self.head = None

在LinkedList中,需要存储的唯一信息是链表的开始位置(链表的头部)。接下来,创建另一个类Node来表示链表的每个节点:

class Node:def __init__(self, data):self.data = dataself.next = None

我们可以给刚创建的两个类添加 __repr__ 方法, 在创建实例的时候输出更多有用的信息:

class LinkedList:def __init__(self):self.head = None
def __repr__(self):node = self.headnodes = []while node is not None:nodes.append(node.data)node = node.nextnodes.append("None")return " -> ".join(nodes)

我们可以给刚创建的两个类添加 __repr__ 方法, 在创建实例的时候输出更多有用的信息

class Node:def __init__(self, data):self.data = dataself.next = Nonedef __repr__(self):return self.data

创建测试类, 测试上面的代码

from LinkedList import LinkedList
from Node import Node
if __name__ == '__main__':llist = LinkedList()print(llist)first_node = Node('a')llist.head = first_nodeprint(llist)second_node = Node('b')third_node = Node('c')first_node.next = second_nodesecond_node.next = third_nodeprint(llist)

修改__init__ 方法,可以传入列表快速创建LinkedList

def __init__(self, nodes=None):self.head = Noneif nodes is not None:node = Node(data=nodes.pop(0))self.head = nodefor elem in nodes:node.next = Node(data=elem)node = node.next

创建__iter__ 方法,遍历链表

def __iter__(self):node = self.headwhile node is not None:yield nodenode = node.next
from LinkedList import LinkedList
if __name__ == '__main__':llist = LinkedList(['a','b','c','d','e'])print(llist)
for node in llist:print(node)

实现链表,添加节点

在头部添加Node:在链表的开头添加一个Node,不必遍历链表,只需将新的Node的next属性指向 self.head ,并将新的node设置为新的 self.head

def add_first(self, node):node.next = self.headself.head = node
from LinkedList import LinkedList
from Node import Node
if __name__ == '__main__':llist = LinkedList()print(llist)llist.add_first(Node('b'))print(llist)llist.add_first(Node('a'))print(llist)

在尾部添加Node:必须遍历链表,与list不同,list可以直接获取长度, 链表只有从第一个Node,不断的去获取下一个Node 才能知道链表的尾部。

def add_last(self, node):if self.head is None:self.head = nodereturnfor current_node in self:passcurrent_node.next = node
from LinkedList import LinkedList
from Node import Node
if __name__ == '__main__':llist = LinkedList(['a','b','c','d'])print(llist)llist.add_last(Node('e'))print(llist)llist.add_last(Node('f'))print(llist)

在指定元素后添加Node:遍历链表找到目标Node, 把目标Node的下一个元素, 赋值给要添加Node的next属性, 然后修改目标Node的next属性, 指向新添加的Node, 当链表为空以及目标元素不存在时抛出异常。

def add_after(self, target_node_data, new_node):if self.head is None:raise Exception("List is empty")
for node in self:if node.data == target_node_data:new_node.next = node.nextnode.next = new_nodereturnraise Exception("Node with data '%s' not found" % target_node_data)

在指定元素后添加Node:遍历链表找到目标Node, 把目标Node的下一个元素, 赋值给要添加Node的next属性, 然后修改目标Node的next属性, 指向新添加的Node, 当链表为空以及目标元素不存在时抛出异常。

from LinkedList import LinkedList
from Node import Node
if __name__ == '__main__':llist = LinkedList()llist.add_after("a", Node("b"))llist = LinkedList(['a','b','c','d'])print(llist)llist.add_after("c", Node("cc"))print(llist)llist.add_after("f", Node("g"))

在指定元素前添加Node:遍历链表找到目标Node,还需要记录当前节点的前一个节点。

def add_before(self, target_node_data, new_node):if self.head is None:raise Exception("List is empty")if self.head.data == target_node_data:return self.add_first(new_node)prev_node = self.headfor node in self:if node.data == target_node_data:prev_node.next = new_nodenew_node.next = nodereturnprev_node = noderaise Exception("Node with data '%s' not found" % target_node_data)
from LinkedList import LinkedList
from Node import Node
if __name__ == '__main__’:llist = LinkedList()llist.add_before("a", Node("b"))llist = LinkedList(["b", "c"])print(llist)llist.add_before('b',Node('a'))print(llist)llist.add_before("b", Node("aa"))llist.add_before("c", Node("bb"))print(llist)llist.add_before("n", Node("m"))

删除Node:遍历链表找到目标Node,将目标Node的前一个Node的next属性,指向目标Node的next节点。

def remove_node(self, target_node_data):if self.head is None:raise Exception("List is empty")if self.head.data == target_node_data:self.head = self.head.nextreturnprevious_node = self.headfor node in self:if node.data == target_node_data:previous_node.next = node.nextreturnprevious_node = node
raise Exception("Node with data '%s' not found" % target_node_data)
from LinkedList import LinkedList
from Node import Node
if __name__ == '__main__’:llist = LinkedList(["a", "b", "c", "d", "e"])print(llist)llist.remove_node("a")print(llist)llist.remove_node('e')print(llist)

Python中的链表和数组如何区分?相关推荐

  1. python中2d_【IT专家】如何在Python中复制一个2D数组?(复制)

    本文由我司收集整编,推荐下载,如有疑问,请与我司联系 如何在 Python 中复制一个 2D 数组? ( 复制 ) 如何在 Python 中复制一个 2D 数组 ?( 复制 )[ 英 ]How to  ...

  2. Python中利用numpy将数组(矩阵)存成csv文件,将csv文件读取为数组(矩阵)

    Python中利用numpy将数组(矩阵)存成csv文件,将csv文件读取为数组(矩阵) 本博客转载自:https://blog.csdn.net/vernice/article/details/50 ...

  3. python中的二维数组_Python中的二维数组实例(list与numpy.array)

    关于python中的二维数组,主要有list和numpy.array两种. 好吧,其实还有matrices,但它必须是2维的,而numpy arrays (ndarrays) 可以是多维的. 我们主要 ...

  4. python中的二维数组与一维数组,矩阵和一维数组之间的运算

    一.python中的二维数组和一维数组之间的运算 1.当二维数组为p×p维 a=np.array([[1,2],[3,4]]) print(a.shape) a 输出: (2, 2) array([[ ...

  5. 如何在Python中定义二维数组

    我想定义一个没有初始化长度的二维数组,如下所示: Matrix = [][] 但这不起作用... 我已经尝试过下面的代码,但是它也是错误的: Matrix = [5][5] 错误: Traceback ...

  6. 两种思路将Python中两个有序数组合并为一个有序数组

    第一种思路: 把两个数组合为一个数组然后再排序,问题又回归到冒泡和快排了,没有用到两个数组的有序性. 第二种思路: 循环比较两个有序数组头位元素的大小,并把头元素放到新数组中,从老数组中删掉,直到其中 ...

  7. python中如何定义一个数组_Python数组定义方法

    本文实例讲述了Python数组定义方法.分享给大家供大家参考,具体如下: Python中没有数组的数据结构,但列表很像数组,如: a=[0,1,2] 这时:a[0]=0, a[1]=1, a[[2]= ...

  8. python中定义变量和数组_Python中的线程和全局变量 - 数组和标准变量之间的区别?...

    我目前尝试使用线程编写一个更大的python程序,并遇到了数组不必被声明为全局的问题.Python中的线程和全局变量 - 数组和标准变量之间的区别? import numpy as np import ...

  9. python中序列类型和数组之间的区别_「Python」序列构成的数组

    一.Python 标准库的序列类型分为: 容器序列: 能够存放不同类型数据的序列(list.tuple.collections.deque). 扁平序列: 只能容纳一种类型的数据(str.bytes. ...

最新文章

  1. squid在企业网中的应用
  2. php7 windows2008,【笔记】Windows Server2008 R2 安装 PHP7 缺少 API-ms-win-crt-runtime-l1-1-0.dll 解决方案...
  3. 测试DeltaCopy
  4. 【C语言练习】求两个数m和n的最大公约数(辗转相除法)
  5. ASP.NET Core MVC四种枚举绑定方式
  6. CodeForces730E Award Ceremony(拓扑排序+结论)
  7. 洛谷P3205合唱队——区间DP
  8. 祝贺!王春雨入职一个月晋升副教授
  9. Android 和 PHP 之间进行数据加密传输
  10. 关于如何提高代码执行效率。
  11. windows借鉴linux了吗,Windows应该借鉴Linux的10大功能特征
  12. Redis字符串类型的操作
  13. html网页毕业论文,HTML网页设计毕业论文.pdf
  14. Maven最新版的下载与安装教程(详细教程)
  15. 自适应遗传算法(AGA)《Adaptive Probabilities of Crossover》的剖析
  16. C++ 万年历、生肖判断、计算第几天
  17. css3 3d 太阳系,CSS3实现的太阳系行星系统
  18. 详解WSAEventSelect网络模型
  19. 仿百度糯米TP5项目笔记
  20. markdown左对齐

热门文章

  1. Python 将控制台输出另存为日志文件
  2. 计算机网络技术数字地球,“数字地球”是指把整个地球信息进行数字化后,由计算机网络来管理的技...
  3. 大牛们的讨论,非常棒,推荐推荐--微信支付能颠覆支付宝吗?传统企业如何互联网化?
  4. ECE 251A MATLAB3
  5. 陀螺仪数据转换成角度_陀螺仪编写实时角度的计算公式?
  6. 谷歌maps菜单语言设置_如何在Google Maps中测量跑步,骑自行车和徒步旅行的距离...
  7. 计算机证书一级难考吗,计算机一级证书有什么用 考试难不难
  8. 落地广州!百度智能云开物来了
  9. R 语言实现股票数据的预处理及分析
  10. python求等差数列第n项_函数实现计算等差数列的第n项