python 链表和列表_天生我才必有用——浅析Python列表与链表

前言

以前写了一篇《没有指针,Python如何实现链表、二叉树这些数据结构》而后有大佬以为我那里面讲的是列表,不是链表。当时我也很疑惑,由于我也不太肯定列表和链表到底有什么区别,说实话,列表确实比较好用,由于是Python已经封装好了的,方法种类多样,更加的实用。可是这难道就意味着链表这一数据结构没有丝毫的用处嘛?固然不是,只是可能你尚未到非用他不可的地步罢了。node

列表详解

列表的实现机制

Python标准类型list就是一种元素个数可变的线性表,能够加入和删除元素,并在各类操做中维持已有元素的顺序(即保序),并且还具备如下行为特征:

基于下标(位置)的高效元素访问和更新,时间复杂度应该是O(1);

为知足该特征,应该采用顺序表技术,表中元素保存在一块连续的存储区中。

容许任意加入元素,并且在不断加入元素的过程当中,表对象的标识(函数id获得的值)不变。

为知足该特征,就必须能更换元素存储区,而且为保证更换存储区时list对象的标识id不变,只能采用分离式实现技术。

在Python的官方实现中,list就是一种采用分离式技术实现的动态顺序表。这就是为何用list.append(x) (或 list.insert(len(list), x),即尾部插入)比在指定位置插入元素效率高的缘由。

在Python的官方实现中,list实现采用了以下的策略:在创建空表(或者很小的表)时,系统分配一块能容纳8个元素的存储区;在执行插入操做(insert或append)时,若是元素存储区满就换一块4倍大的存储区。但若是此时的表已经很大(目前的阀值为50000),则改变策略,采用加一倍的方法。引入这种改变策略的方式,是为了不出现过多空闲的存储位置。python

翻阅了多方的资料,看了其余一些大佬发的东西,我在这里总结一下:

列表的实现能够是数组或者链表。而且经过前面的学习咱们知道,列表是一种顺序表,顺序表通常是数组。列表是一个线性表,它容许用户在任何位置进行插入、删除、访问和替换元素。

列表的实现是基于数组或者基于链表结构,当使用列表迭代器的时候,双向链表结构比单链表结构更快。

Python中的列表英文名是list,所以很容易与C语言中的链表搞混了,由于在C语言中你们常常给链表命名为list。事实上CPython(CPython是指用C语言实现的Python,也是咱们常见的用C语言开发的Python解释器,你们应该都知道,Python语言底层是C语言实现的)中的列表根本不是列表。在CPython中列表被实现为长度可变的数组。

从细节上看,Python中的列表是由其余对象的引用组成的连续数组,指向这个数组的指针及其长度被保存在一个列表头结构中。这就意味着,每次添加或删除一个元素时,由引用组成的数组须要改变大小(从新分配)。幸运的是,Python在建立这些数组时采用了指数分配,因此并非每次操做都要改变数组的大小。可是,也由于这个缘由添加或者取出元素是平摊复杂度较低。不幸的是,在普通链表上“代价很小”的其余一些操做在Python中计算复杂度相对较高。

总的来讲,Python中的列表是一个动态的顺序表,而顺序表大可能是由数组实现的。web

链表

Python链表的具体实如今我上面那篇文章里面介绍过了。我这里就再来炒个剩饭。

链表是由许多相同数据类型的数据项按照特定的顺序排列而成的线性表。链表中的数据项咋计算机的内存中的位置是不连续且随机的,然而列表是连续的。链表数据的插入和删除是很方便的,但数据的查找效率较低,不能像列表同样随机读取数据。

链表由一个一个的结点构成,每一个结点由数据域和“指针域”组成,数据域存储数字,“指针域”指向下一个结点所在的内存地址。(由于Python中没有指针这一律念的,这里的指针是一种指向)数组

class Node(object):

"""节点"""

def __init__(self, elem):

self.elem = elem

self.next = None

链表封装的一系列操做:服务器

class SingleLinkList(object):

"""单链表"""

def __init__(self, node=None):

self.__head = node

def is_empty(self):

"""链表是否为空"""

return self.__head == None

def length(self):

"""链表长度"""

# cur游标,用来移动遍历节点

cur = self.__head

# count记录数量

count = 0

while cur != None:

count += 1

cur = cur.next

return count

def travel(self):

"""遍历整个链表"""

cur = self.__head

while cur != None:

print(cur.elem, end=" ")

cur = cur.next

print("")

def add(self, item):

"""链表头部添加元素,头插法"""

node = Node(item)

node.next = self.__head

self.__head = node

def append(self, item):

"""链表尾部添加元素, 尾插法"""

node = Node(item)

if self.is_empty():

self.__head = node

else:

cur = self.__head

while cur.next != None:

cur = cur.next

cur.next = node

def insert(self, pos, item):

"""指定位置添加元素

:param pos 从0开始

"""

if pos <= 0:

self.add(item)

elif pos > (self.length()-1):

self.append(item)

else:

pre = self.__head

count = 0

while count < (pos-1):

count += 1

pre = pre.next

# 当循环退出后,pre指向pos-1位置

node = Node(item)

node.next = pre.next

pre.next = node

def remove(self, item):

"""删除节点"""

cur = self.__head

pre = None

while cur != None:

if cur.elem == item:

# 先判断此结点是不是头节点

# 头节点

if cur == self.__head:

self.__head = cur.next

else:

pre.next = cur.next

break

else:

pre = cur

cur = cur.next

def search(self, item):

"""查找节点是否存在"""

cur = self.__head

while cur != None:

if cur.elem == item:

return True

else:

cur = cur.next

return False

链表与列表的差别

Python中的list(列表)并非传统意义上的列表,传统的意义上的列表就是咱们今天讲的链表,链表真的是跟列表长的很像的啊,不一样地方在于链表在数据存储方面更加的自由,其带有指示下一个结点未知的指向,也就是我能够随意的存储数据,只要咱们有东西能找到我,我也能够找到个人下一个。而列表则只能分配在一段连续的存储空间里,且是做为一个总体,这就大大限制了数据的变动操做,但其在进行一些基础简单的操做时,时间复杂度极低。

list(列表):动态的顺序表

链表:存储地址分散的,须要“指针”指向的线性表网络

为何要学习链表

知乎中的一个高赞回答:数据结构

我以为家里的承重墙没实际意义,正忙着拆它呢。有事等我拆完了再说。

拆完了。

链表插入删除效率极高,达到O(1)。对于不须要搜索但变更频繁且没法预知数量上限的数据,好比内存池、操做系统的进程管理、网络通讯协议栈的trunk管理等等等等,缺了它是绝对玩不转的。

甚至就连不少脚本语言都有内置的链表、字典等基础数据结构支持。哪怕只是稍微像点样子的小项目,若是缺了链表……谁扔的小石子?……啊,缺了链表绝对玩不转。保守估计,缺了链表,普通家用PC至少得慢10倍,网络服务器慢数百到数万倍都有可……啊,房子要塌app

Python实现链表这一数据结构能简化咱们的阅读,他没有C语言里面一大堆指针和内存分配那样的晦涩难懂,站在了一种更高层次的地方来方便快捷的实现链表这一数据结构,易于你们的理解。svg

后记

害!我也不知道我讲清楚了没得,列表和链表这个玩意儿确实是傻傻分不清,怪就怪在Python封装了一个这么好的列表,让链表这个兄弟在大多数的时候都没地方混,列表是真的好用,可是咱们为了学习数据结构也应该要掌握一下链表。

你们能够参考一下其余大佬写的文章:

python学习笔记 – list内部实现(转)https://www.jianshu.com/p/cd75475168a

Python的列表(List)的底层实现原理 https://blog.csdn.net/Yuyh131/article/details/83592608

毕竟是新手,写的很差或者不对的地方欢迎指正,一块儿加油!

新手上路,技术有限,不喜勿喷!函数

你可能感兴趣的:(python,链表和列表)