python实现单向循环链表

单向循环链表

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

python实现单向循环链表_第1张图片

操作

  • is_empty() 判断链表是否为空
  • length() 返回链表的长度
  • travel() 遍历
  • add(item) 在头部添加一个节点
  • append(item) 在尾部添加一个节点
  • insert(pos, item) 在指定位置pos添加节点
  • remove(item) 删除一个节点
  • search(item) 查找节点是否存在

实现

# 节点, 包括:元素和下一个节点的地址
class Node(object):
    def __init__(self, elem):
        self.elem = elem
        self.next = None


class SingleLoopLinkList(object):
    '''单向循环链表'''
    def __init__(self, node=None):
        self.__head = node

    def is_empty(self):
        '''链表是否为空'''
        return self.__head == None

    def length(self):
        '''链表长度'''
        # 如果链表为空返回0
        if self.is_empty():
            return 0

        count = 1
        cur = self.__head

        while cur.next != self.__head:
            count += 1
            cur = cur.next

        return count

    def travel(self):
        '''遍历整个链表'''
        # 如果链表为空,即返回为空
        if self.is_empty():
            return

        cur = self.__head

        while cur.next != self.__head:
            print(cur.elem, end=' ')
            cur = cur.next
        # 打印最后一个元素
        print(cur.elem, end=' ')

    def add(self, item):
        '''链表头部添加元素'''
        node = Node(item)
        if self.is_empty():
            self.__head = node
            node.next = self.__head
        else:
            # 添加的节点指向__head
            node.next = self.__head
            # 移到链表尾部,将尾部节点的next指向node
            cur = self.__head
            while cur.next != self.__head:
                cur = cur.next
            cur.next = node
            # __head指向添加node的
            self.__head = node


    def append(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
            # 将尾节点next指向node
            cur.next = node
            # 将添加的节点next指向头节点
            node.next = self.__head

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

        # 如果位置在第一个元素之前,就往头添加
        if pos <= 0:
            self.add(item)

        # 如果位置在最后一个元素之后,就往尾添加
        elif pos > self.length() - 1:
            self.append(item)

        else:
            cur = self.__head
            count = 0

            while count < pos -1:
                count += 1
                cur = cur.next

            node = Node(item)
            # 先将新节点node的next指向插入位置的节点
            node.next = cur.next
            # 将插入位置的前一个节点的next指向新节点
            cur.next = node

    def remove(self, item):
        '''删除节点'''
        if self.is_empty():
            return
        cur = self.__head
        pre = None

        while cur.next != self.__head:
            if cur.elem == item:
                # 如果是头节点
                if not pre:
                    # 需要改变尾节点的指向,所以先要找到尾节点
                    rear = self.__head
                    while rear.next != self.__head:
                        rear = rear.next
                    self.__head = cur.next
                    rear.next = self.__head
                # 如果为中间节点
                else:
                    # 将删除位置的上一个节点next指向删除位置的下一个节点
                    pre.next = cur.next
                return
            else:
                pre = cur
                cur = cur.next
        # 退出循环
        # 如果为尾节点
        if cur.elem == item:
            # 如果就只有一个节点
            if cur == self.__head:
                self.__head = None
            else:
                # 尾节点的上一个节点next指向头节点
                pre.next = self.__head

    def search(self, item):
        '''查找节点是否存在'''
        # 如果为空,就直接返回-1
        if self.is_empty():
            return -1
        else:
            cur = self.__head
            count = 0

            while cur.next != self.__head:
                if cur.elem == item:
                    return count
                else:
                    cur = cur.next
                    count += 1
            # 判断最后一个节点是否为item
            if cur.elem == item:
                return count

            return -1


# 测试
if __name__ == '__main__':
    sll = SingleLoopLinkList()
    # 判断是否为空
    print(sll.is_empty())
    # 获取链表长度
    print(sll.length())
    # 遍历链表
    sll.travel()
    # 头添加元素
    sll.add(1)
    sll.add(100)
    print(sll.is_empty())
    print(sll.length())
    sll.travel()
    print()
    # 尾添加元素
    sll.append(300)
    sll.append(400)
    sll.travel()
    print()
    # 指定位置添加元素
    sll.insert(3, 200)
    sll.insert(6, 500)
    sll.travel()
    print()
    # 删除节点
    sll.remove(1)
    sll.travel()
    print()
    # 查找节点
    print(sll.search(200))

你可能感兴趣的:(python数据结构与算法)