python中什么相当于链表_python数据结构之链表(一)

2020-07-09更新

细细琢磨了一下以前的这篇文章,感觉这样不太能体现链表的精髓,要想真的想深入研究链表这种数据结构,在没有指针的语言中,还是应该用静态链表来模拟真正链表比较好。

对于静态链表,个人认为要先想想下面几点:

静态链表的存储结构是什么?

没有指针,怎么来模拟指针?怎么模拟C语言中地址的概念

怎么去模拟内存管理?

OK, 先来聊聊第1、2点,静态链表在没有指针的语言中用数组来实现,用一组地址连续的存储单元来存放数据(第一次了解到这里,我也是懵圈的,数组???这不就是顺序表吗,怎么和链表扯上关系?),有意思的就来了,我们就用数组的下标来代替地址吧!!!对,要学会静态链表,你就先要把数组看做一个内存空间,数组下标就是这个空间的地址。C有指针就相当于可以在整个内存空间的海洋里遨游,而静态链表就是只能在自己搭建的舞台上起舞。

当你认识到数组来模拟一片内存空间,下标就是地址的时候,我们就要来解决实际问题了,也就是怎么模拟内存的管理?

一、肯定是定义节点item类,其中data保存数据,next保存下一个节点的下标(也可以理解为下一个的位置或者地址),静态链表类SLinkList,在初始化函数__init__里创建一个size+1大小的列表link(因为我的设计是将0节点设为头结点,不保存数据,用来记录链表长度length,链表尾部rear等信息)。

现在内存空间创建好了,那么问题又来了,我们怎么知道哪些节点是链表里面的,哪些节点是空闲的?在这里我想到了一个比较巧妙的方法,不用另外创建一个数组去存储空闲空间信息。因为初始化的时候所有的空间都是空闲的,我们可以先将所有的空闲节点连起来(也就是第i个节点保存第i+1个节点的位置),然后头结点用一个变量space指向第一个空闲空间的位置,这样我们就保持space永远指向一个空闲节点的位置,即可随时知道那个位置是空闲的了。代码如下,通过代码可以比较直观的理解我的意思。

1 classitem (object):2 def __init__(self, data):3 self.data =data4 self.next =None5

6 classSLinkList(object):7 '''

8 静态链表,就是用数组来模拟链表,那么数组的下标就当做是节点的地址,9 这个概念是静态链表的核心10 '''

11 def __init__(self, size = 100):12 '''

13 初始化主要是用于初始化链表的大小,而非创建链表14 '''

15 self.link = [item(None) for i in range(size + 1)] #申请size大小的节点空间[0,1,2,...,size],其中下标0的节点作为头结点

16 self.link[0].next = None #表示空表

17 self.link[0].space = 1 #指向第一个节点,因为初始化时第一个节点为空闲节点

18

19 i = 1

20 while i <21 self.link i>

22 i += 1

23

24 self.link[i].next = None #空闲表尾指向None

25

26 self.length = 0 #链表长度

27 self.rear = 0 #表尾指针

二、空闲空间已经有了,那么要怎么管理这片空间呢?C语言中新建一个节点会先用malloc函数申请一个内存空间,删除一个节点我们会用free函数来释放内存,在静态链表中我们需要自己实现,因为之前头结点space永远都会指向一个空闲节点的位置,所有我设计的malloc_SL函数,直接从space获取一个空闲节点的位置,然后space再指向下一个空闲节点位置即可,而释放空间函数free_SL同理,先将待释放的点保存space指向的空闲位置,再将space指向该点即可模拟内存回收的过程。代码如下:

1 defMalloc_SL(self):2 '''

3 类似于C中malloc函数申请空间,返回空闲节点的下标4 '''

5 i =self.link[0].space6 ifself.link[0].space:7 self.link[0].space =self.link[i].next8

9 returni10

11 defFree_SL(self, k):12 '''

13 释放空间,并返回下标k节点的值14 '''

15 self.link[k].data =None16 self.link[k].next =self.link[0].space17 self.link[0].space = k

三、完成上面两点,静态链表的核心基本就说完了,其他的增删改查操作和c中的链表就差不多了,再提一次就是,静态链表的数组下标就相当于位置,地址!这里我再介绍一下的往链表末尾添加节点的操作函数Append(),流程就是先用Malloc_SL函数申请一个空间节点的位置,然后在该位置添加数据,next指向None,成为新的表尾,再将表尾指针指向该新加入的节点,表长length + 1,代码如下:

1 defAppend(self, data):2 '''往链表表尾添加元素, 并返回新添加元素的下标'''

3 node_index =self.Malloc_SL()4

5 if notnode_index:6 print("Append: NO SPACE!")7 returnFalse8

9 self.link[node_index].data =data10 self.link[node_index].next =None11 self.link[self.rear].next =node_index12 self.rear =node_index13 self.length += 1

14 return node_index

四、最后我实现了几个链表的操作,其他操作有读者自己去琢磨:

CreateSLinkList_R---->用尾插法插入元素,创建一个链表

CreateSLinkList_F---->用头插法插入元素,创建一个链表

DeleteElement--------->根据数据删除第一个匹配到的节点

InsertBefore------------>在第k个节点前插入新节点

Walk--------------------->遍历整个链表,并输出数据

Detail-------------------->输出各节点的详细信息

全部代码如下:

1 classitem (o

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值