Python进阶学习(5)—单向循环链表(超详细)

单向循环链表

循环链表
循环链表是一种特殊的单链表。实际上,循环链表也很简单。它跟单链表唯一的区别就在尾结点。我们知道,单链表的尾结点指针指向空地址,表示这就是最后的结点了。而循环链表的尾结点指针是指向链表的头结点。从我画的循环链表图中,你应该可以看出来,它像一个环一样首尾相连,所以叫作“循环”链表。
在这里插入图片描述
操作
is_empty() 判断链表是否为空
length() 返回链表的长度
travel() 遍历
add(item) 在头部添加一个节点
append(item) 在尾部添加一个节点
insert(pos, item) 在指定位置pos添加节点
remove(item) 删除一个节点
search(item) 查找节点是否存在

其代码实现

class Node(object):
    '''设置节点'''
    def __init__(self,item):
        self.item = item # 节点的数据区
        self.next = None # 节点的链接区
class SinCycLinkList(object):
    '''单项循环节点'''
    def __init__(self,node = None):
        self.head = node # 设置首节点
        if node:
            node.next = node

    def is_empty(self):
        """判断链表是否为空"""
        if self.head == None:
            return True
        return False

    def length(self):
        """返回链表的长度"""
        cur = self.head # 设置游标cur指向头节点
        count = 1
        if self.is_empty(): # 判断链表是否为空
            return 0
        else:  # 链表不为空时
            while cur.next!= self.head: # 将游标移动到最后一个节点处,注意这里设置的是count= 1,是因为循环的时候游标在最后一个指向
                count += 1
                cur = cur.next
        return count # 返回count

    def travel(self):
        """遍历链表"""
        if self.is_empty(): # 判空
            return None
        else: # 当链表不为空时
            cur = self.head
            while cur.next != self.head:
                print(cur.item,end = ' ')
                cur = cur.next # 这里循环到最后一个节点处
            print(cur.item) # 打印最后一个节点的数据区

    def add(self, item):
        """链表头部添加元素"""
        node = Node(item) # 创建新节点

        if self.is_empty(): # 判空,如果为空
            self.head = node # 将新节点赋值给头节点
            node.next = self.head # 由于是单向循环链表,构成循环

        else: # 如果不为空
            cur = self.head # 将链表指向头节点
            while cur.next != self.head:
                cur = cur.next # 将节点循环到最后一个节点处
            node.next = self.head # 将原来的头节点赋值给新节点的链接区
            self.head = node # 将新节点赋值给头节点
            cur.next = node # 新头节点和尾节点构成循环

    def append(self, item):
        """链表尾部添加元素"""
        node = Node(item) # 创建新节点
        if self.is_empty(): # 判空
            self.add(item) # 如果为空,就给头部添加
        else: # 如果不为空时
            cur = self.head # 设置cur游标指向头节点
            while cur.next != self.head:
                cur = cur.next # 循环到最后一个节点处
            node.next = self.head # 将头节点赋值给新节点的链接区
            cur.next = node # 将新节点赋值给原尾节点的链接区

    def insert(self, pos, item):
        """指定位置添加元素"""

        if pos <= 0: # pos 为要添加到的位置,这里和单链表一样,按照坐标轴的顺序,当插入的位置小于0时,就默认判断给第一位添加
            self.add(item)
        elif pos > self.length() - 1: # # 当插入的位置大于链表长度时,默认给链表最后一位添加
            self.append(item)
        else: # 当添加的位置在链表长度之内时
            node = Node(item) # 创建新节点
            pre = self.head # pre为要添加位置的上一个节点,设置初始值为None
            count = 0
            while count < pos - 1:
                count += 1
                pre = pre.next # 将pre循环到要添加位置的上一个节点处
            node.next = pre.next # 将pre节点的链接区赋值给新节点的链接区
            pre.next = node # 将新节点指向pre的链接区

    def search(self, item):
        """查找节点是否存在"""
        if self.is_empty():# 判空
            return False
        else:
            cur = self.head # 设置游标为头节点
            while cur.next != self.head:
                if cur.item == item: # 判断要查找的数据与节点数据区比较
                    return True
                else:
                    cur = cur.next # 循环节点
            if cur.item == item: # 上面循环指向完之后游标指向尾节点
                return True
            return False

    def remove(self, item):
        """删除节点"""
        if self.is_empty(): # 判空
            return
        cur = self.head # 设置游标
        pre = None # 设置要移除节点的上一个节点

        # 头节点是要删除的
        if cur.item == item:
            if cur.next != self.head: # 当链表长度不为1时
                while cur.next != self.head:
                    cur = cur.next # 循环到最后一个节点
                cur.next = self.head.next # 将头节点的链接区指向最后一个节点的链接区,构成循环
                self.head = cur.next # 将尾节点的链接区指向首节点
        else:  # 头节点不是要删除的,这里和单链表一样
            while cur.next != self.head:
                if cur.next == item :
                    pre.next = cur.next
                else:
                    pre = cur
                    cur = cur.next
            if cur.item == item:# 最后循环到最后一个节点处,比较尾节点的数据区与要查找的数据
                pre.next = cur.next

在这里说明一下,只要是要循环到尾节点的操作的函数内,都要先判空,而且还要注意循环到尾节点处,尾节点的数据区还没有判断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值