Python 新手刚学链表,做了一个“捣浆糊”版的单链表类

链表定义

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

单向链表,又叫单链表、单向表,是由一个个节点组成的,每个节点是一种信息集合,包含元素本身以及下一个节点的地址。节点在内存中是非连续分布的,在程序运行期间,根据需要可以动态的创建节点,这就使得链表的长度没有逻辑上的限制,有限制的是堆的大小。

在单向链表中,每个节点中存储着下一个节点的地址。基于单向链表,在每个节点内增加一个前驱节点的地址,这就是所谓的双向链表,又叫双链表、双向表。

如单向链表的尾节点指针指向头节点,即为循环单向链表
如单向链表的头、尾节点指针互相指,即为循环双向链表

指针是C/C++等语言中的概念,也就是内存地址;python中没有指针,也很少直接操作地址。
在 python 这一类没有指针的语言里,很难真正体现出链表的精髓,只能模拟出一个静态链表来意思意思。

单向表类的实现

模仿python中二叉树的节点Node类,把左右子树的left,right换成一个Next,就有点像了。因为刚学python不久功力有限,愣是用字符串和列表,伪实现了一个单向表的类:

class Node():
    def __init__(self,val=None,Next=None):
        self.val = val
        self.Next = Next
            
    def __repr__(self):
        return 'listNode('+str(self.val)+')'

    def __getitem__(self, slices):
        list = self.values()
        return list[slices]

    def is_empty(self):
        return self.val is None

    def value(self):
        return self.val

    def values(self):
        head = self
        t = 'head'
        r = []
        while eval(t) is not None:
            r.append(eval(t).val)
            t+='.Next'
        return r

    def size(self):
        if self.is_empty():
            return 0
        r = self.values()
        return len(r)

    def append(self, node):
        if self.val is None:
            self.val = node
            return
        head = self
        t = 'head'
        while eval(t) is not None:
            t+='.Next'
        exec(f'{t}=Node({node})')

    def pop(self):
        head = self
        if head.size() < 2:
            res = head.val
            head.val = None
            return res
        t = 'head'
        while eval(t).Next is not None:
            t+='.Next'
        res = eval(t).val
        exec(f'{t}=None')
        return res
    
    def pprint(self):
        r = self.values()
        r = [i.join(["'"]*2) if type(i) is str else str(i) for i in r]
        print('->'.join(r))

之所以说是“伪实现”,因为根本就是用字符串和列表模拟出来的效果。尽管这个类如此不入门,有点傻傻的,用上海咸话的讲法,称之为“捣浆糊”。但还是能完成不少功能的。呈上测试代码,如下:

1. 逐个赋值

>>> LinkedList = Node()
>>> LinkedList.is_empty()
True
>>> LinkedList.size()
0
>>> LinkedList = Node(1)
>>> LinkedList.is_empty()
False
>>> LinkedList.size()
1
>>> LL = LinkedList
>>> LL.Next = Node(2)
>>> LL
listNode(1)
>>> LL.Next
listNode(2)
>>> LL.val
1
>>> LL.Next.val
2
>>> LL.value()
1
>>> LL.Next.value()
2
>>> LL.values()
[1, 2]
>>> 
>>>
>>> LinkedList = Node()
>>> LinkedList = Node(1,Node(2))
>>> linked = Node(1,Node(2))
>>> linked.Next.Next = Node('3',Node(4))
>>> linked.pprint()
1->2->'3'->4
>>> linked.values()
[1, 2, '3', 4]
>>> 

注:此链表类允许数字、字符串混装 

2.追加append()和弹出pop()

>>> single = Node(1,Node(2,Node(3,Node(4,Node(5)))))
>>> single.pprint()
1->2->3->4->5
>>> single.append(6)
>>> single.pprint()
1->2->3->4->5->6
>>> single.pop()
6
>>> single.pop()
5
>>> single.pprint()
1->2->3->4
>>> 

 3. 嵌套赋值或用循环赋值

>>> single = Node(1,Node(2,Node(3,Node(4,Node(5)))))
>>> single.size()
5
>>> single.values()
[1, 2, 3, 4, 5]
>>> 
>>> 
>>> link = Node()
>>> for i in range(1,9):
	link.append(i)

	
>>> link.pprint()
1->2->3->4->5->6->7->8
>>> 

4. 索引和切片

>>> lList = Node()
>>> t = [lList.append(i) for i in range(1,9)]
>>> lList.pprint()
1->2->3->4->5->6->7->8
>>> lList[:]
[1, 2, 3, 4, 5, 6, 7, 8]
>>> lList[::-1]
[8, 7, 6, 5, 4, 3, 2, 1]
>>> lList[0]
1
>>> lList[1]
2
>>> lList[7]
8
>>> lList[-1]
8
>>> lList[-2]
7
>>> lList[-8]
1
>>> lList[:5]
[1, 2, 3, 4, 5]
>>> lList[5:]
[6, 7, 8]
>>> lList[::2]
[1, 3, 5, 7]
>>> lList[1::2]
[2, 4, 6, 8]
>>> 

注:链表一般是不带索引功能的,这里用类的内置方法__getitem__(self, slices)来强加一个索引和切片的功能,完全是继承了列表的功能。

5. 删除和插入

>>> single = Node(1,Node(2,Node(3,Node(4,Node(5)))))
>>> single.pprint()
1->2->3->4->5
>>> single.Next.Next = single.Next.Next.Next
>>> single.pprint()
1->2->4->5
>>> 
>>> tmp = single.Next.Next
>>> single.Next.Next = Node(6)
>>> single.Next.Next.Next = tmp
>>> single.pprint()
1->2->6->4->5
>>> 

注:删除和插入方法没有直接写进这个类里,但也能用代码实现类似操作。

单链表真实的删除和插入操作过程,如下所示:

6. 单链表的反转(倒序)

>>> linked = Node()
>>> assign = [linked.append(i) for i in range(1,9)]
>>> linked.pprint()
1->2->3->4->5->6->7->8
>>> tmp,linked = linked,Node()
>>> while not tmp.is_empty():
	linked.append(tmp.pop())

	
>>> linked.pprint()
8->7->6->5->4->3->2->1
>>> 

注:用循环反复追加append原链表的pop()返回值完成倒序操作。
 

“捣浆糊”版的链表类就到此结束吧,准备下一篇再来重写一个进阶一点的链表类   ^_^

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的影城管理系统,源码+数据库+论文答辩+毕业论文+视频演示 随着现在网络的快速发展,网上管理系统也逐渐快速发展起来,网上管理模式很快融入到了许多生活之中,随之就产生了“小徐影城管理系统”,这样就让小徐影城管理系统更加方便简单。 对于本小徐影城管理系统的设计来说,系统开发主要是采用java语言技术,在整个系统的设计中应用MySQL数据库来完成数据存储,具体根据小徐影城管理系统的现状来进行开发的,具体根据现实的需求来实现小徐影城管理系统网络化的管理,各信息有序地进行存储,进入小徐影城管理系统页面之后,方可开始操作主控界面,主要功能包括管理员:首页、个人中心、用户管理、电影型管理、放映厅管理、电影信息管理、购票统计管理、系统管理、订单管理,用户前台;首页、电影信息、电影资讯、个人中心、后台管理、在线客服等功能。 本论文主要讲述了小徐影城管理系统开发背景,该系统它主要是对需求分析和功能需求了介绍,并且对系统了详细的测试和总结。具体从业务流程、数据库设计和系统结构等多方面的问题。望能利用先进的计算机技术和网络技术来改变目前的小徐影城管理系统状况,提高管理效率。 关键词:小徐影城管理系统;Spring Boot框架,MySQL数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hann Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值