python nodes函数 python node类_python nodes函数


Python数据结构(二)单向循环链表

回顾:Python数据结构(一)单向链表

上回说到单向链表,可以解决数据因为在内存上不连续存储而无法访问到的问题,这次再介绍单向循环链表,TA和单向链表的唯一区别就在于TA的尾部绳结的next指向的不再是None而是最开头的那个绳结。

一、单向循环链表介绍

为了方便大家的理解,我画了一个单向循环链表的示意图(如下),其中橙色区域代表绳结(Node)的数据(data),蓝色区域代表绳结(Node)存储的下一个绳结(Node)在内存中的起始地址,4byte 表示python 固定用4byte来存储地址信息。


python nodes函数 python node类_链表_02


二、单向循环链表实现

对于绳结(Node)不需要做任何改变,还是跟原来一样。很多人可能会有疑惑,为什么我写的Node会这么长? 其实我是出于健壮性和复用性两个方面来考虑的,首先是在创建新的节点的时候,我们判断传进来的参数类型是否是我们想要的(isinstance()的作用),其次我们的类内部都是私有属性,不能让用户随意拿到,因此用装饰器把属性的get()和set()方法给伪装成属性让用户来使用。


class


绳子的初始化method()需要注意,如果是通过传递实例的方式来构建,需要修改绳结(Node)的next指向。


class


三、功能完善

1 isEmpty() 判断是否为空


def


2 printData() 遍历链表并输出


def


这里和单向链表的while 判断条件有一些不同,由于链表是循环结构,尾部节点不再指向的是None;

特别注意,printdata()中while 的停止条件是迭代到尾部节点,因此为了把链表信息输出完整,还应该在while 之后再加一个print。

3 length() 获取链表长度


def


求长度的时候,判断list是否为空非常关键,可以理解为对一个棘手的边界情况的处理。如果不优先处理空链表,在接下来的while 循环中将出现None.next的尴尬局面。

其次,return+1 是一种必要的处理,因为我们的判断条件是,当到达尾部节点的时候将终止循环,这时候count 计数器是没有把最后这个节点给算进去的,需要我们手动补上。

4 append() 追加元素


def


优先处理空链表的情况,然后不要忘了把新的节点的next 指向头节点。

5 addFromHead() 头部插入


def


这个和单向链表就有很大的区别。因为我们要修改头部节点,意味着我们要同时修改尾部节点信息,所以我们至少需要遍历整个节点找到尾部节点。

6 insert() 指定位置插入


def


看似特殊情况非常多的insert()方法,其实内部的实现和单向链表的是一毛一样的!因为涉及到最关键的两个部位(头节点和尾部节点)都已经被上述的方法给特殊处理了,我们只需要调用即可。

7 deleteByPosition() 指定位置删除

删除操作是一种比较麻烦的操作类型,对于链表来说。众所周知,链表是依靠前后节点相互记住之间的位置信息来实现的,每个节点都不会知道自己在链表的准确位置(除非特地开辟一个数据区存储)以及链表的整体信息如链表长度,因此,如何正确断开某个节点,尤其是头尾节点显得尤为重要。

7.1 deleteFromHead() 头部节点删除


def


7.2 deleteFromTail() 尾部节点删除


def


注意while 循环里的if not 语句,这不是瞎写的,是为了防止链表刚好只有一个节点,而我们要删除的又刚刚好是这个节点。previous_point 初始值为None可以用来做逻辑判断,python中None对应的逻辑值是False。

7.3 deleteByPosition() 指定位置删除


def


这里是本章节最苦难的部分。之所以难是因为有两个特殊情况(删除头节点和删除尾部节点)都需要重新写,为了不让deleteByPosition()太过臃肿,我把这两部分给抽离了出来。

8 deleteByItem() 指定数据删除


def


这是一个稍微不注意就会写出非常繁琐程序的method,在这里只讲一点,就是while 循环之后还要再添加一个if 判断,因为while是只要到达尾部节点就会跳出的循环,需要一个额外检查来检验尾部节点是否是我们要删除的。

9 search() 查找指定元素


def


这是新增的功能,跟printdata()有点类似,需要遍历整个链表来查找元素。

至此,单向链表的基本操作算是实现完成。

完整的单向链表python上传到github上:singleCircularList

更多的关于python 内部数据结构的实现,我会在后续出一系列文章来介绍。

总结

单向循环链表和单向链表最大的区别在于method的实现上对尾部节点和头节点的处理,注意到这点即可,中间部分的增删改查和之前的单向链表是没什么不同的。

下回:

引用

1 circular linked list

2 python_dictionary