Python链表之单向循环链表

单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。

 

 

 

class Node(object):
    """单链表的节点"""
    def __init__(self, item):
        # elem存放数据元素
        self.elem = item
        # next是下一个节点的标识
        self.next = None


class SingleCycleList(object):
    """单向循环链表"""
    def __init__(self):  # 初始化一个空链表
        self._head = None

    def is_empty(self):
        """判断链表是否为空"""
        return self._head is None

    def length(self):
        """链表长度"""
        # 如果链表为空,返回长度0
        if self.is_empty():
            return 0
        # 如果不为空,则开始下面的步骤
        cur = self._head
        # count记录数量
        count = 1
        while cur.next is not self._head:  # 因为时单向循环链表,初始_head指向的是头节点,如果只有一个节点,则该节点的next会指向该节点,所以按照while循环的条件,count从1开始
            count += 1
            cur = cur.next
        return count

    def travel(self):
        """遍历链表"""
        # 如果链表为空,直接返回
        if self.is_empty():
            return
        # cur游标,用来移动遍历节点
        cur = self._head
        while cur.next is not self._head:  # _head指向的是头节点,如果最后一个节点的next指向_head,则表示cur指向的是尾节点
            print(cur.item, end=" ")
            cur = cur.next
        # 退出循环时,cur指向尾节点,但是尾节点的元素未打印
        print(cur.item)

    def add(self, item):
        """头部添加元素,头插法"""
        node = Node(item)
        # 如果链表为空
        if self.is_empty():
            # _head指向需要插入的节点,该节点的next指向该节点
            self._head = node
            node.next = node
        # 链表不为空
        else:
            cur = self._head
            while cur.next is not self._head:
                cur = cur.next
            # 退出循环时,cur指向尾节点
            node.next = self._head  # 需要插入的node节点指向_head指向的节点,即头节点
            self._head = node  # _head指向需要插入的node节点
            cur.next = node  # 尾节点的next指向现在的头节点,即node节点

    def append(self, item):
        """尾部添加元素,尾插法"""
        node = Node(item)
        # 如果链表为空
        if self.is_empty():
            self._head = node
            node.next = node
        else:
            # cur游标,用来移动遍历节点
            cur = self._head
            while cur.next is not self._head:
                cur = cur.next
            # 退出循环,cur指向尾节点,node的next指向cur的next,即node的next指向头节点;cur的next指向node,即node此时为尾节点了
            node.next = cur.next
            cur.next = node

    def insert(self, pos, item):
        """指定位置添加元素
        :param pos:从0开始
        :param item:需要插入的元素
        """
        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):
        """删除节点"""
        # 若链表为空,则直接返回
        if self.is_empty():
            return
        # 将cur指向头节点
        cur = self._head
        pre = None
        # 进入while则表示链表不止1个节点
        while cur.next is not self._head:
            if cur.item == item:
                # 先判断此节点是否是头节点
                if cur == self._head:
                    # 头节点的情况,需要先找尾节点
                    rear = self._head
                    while rear.next is not self._head:
                        rear = rear.next
                    # 退出循环,rear指向尾节点
                    self._head = cur.next  # _head指向cur的下一个,即第二个节点
                    rear.next = self._head  # 尾节点的next指向新的头节点
                else:
                    # 中间节点
                    pre.next = cur.next
                return
            else:
                pre = cur
                cur = cur.next
        # 退出while时,cur指向的是尾节点,没有进行处理
        if cur.item == item:
            if cur == self._head:
                # 链表只有一个节点
                self._head = None
            else:
                pre.next = self._head  # 等同于pre.next = cur.next,让cur的前一个节点指向头节点,完成尾节点的删除

    def search(self, item):
        """链表查找节点是否存在,并返回True或者False"""
        if self.is_empty():
            return False
        cur = self._head
        while cur.next is not self._head:
            if cur.item == item:
                return True
            else:
                cur = cur.next
        # 退出循环时,cur指向尾节点,还需要判断一下cur是否是item
        if cur.item == item:
            return True
        return False


if __name__ == "__main__":
    ll = SingleCycleList()
    print(ll.is_empty())
    print(ll.length())
    ll.add(1)
    print(ll.is_empty())
    print(ll.length())
    ll.append(2)
    ll.append(3)
    ll.append(4)
    ll.travel()
    ll.remove(1)
    ll.travel()
    ll.remove(4)
    ll.travel()
    ll.insert(-1, 1)
    ll.travel()
    ll.insert(6, 4)
    ll.travel()
    res = ll.search(1)
    print(res)

 

posted @ 2021-08-08 21:07  钟胜一  阅读(150)  评论(0编辑  收藏  举报