• 4. 单向循环链表


    (1)单向循环链表定义:

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

        

    (2)操作:

        is_empty():           判断链表是否为空

        length():               返回链表的长度

        travel():                遍历

        add(item):            在头部添加一个节点

        append(item):      在尾部添加一个节点

        insert(pos, item): 在指定位置pos添加节点

        remove(item):      删除一个节点

        search(item):       查找节点是否存在

    (3)实现:    

      1 class Node(object):
      2     """单链表的结点"""
      3     def __init__(self, elem):
      4         # elem存放数据元素
      5         self.elem = elem
      6         # next是下一个节点的标识
      7         self.next = None
      8 
      9 class SingleCycleLinkList(object):
     10     """单向循环链表"""
     11     def __init__(self, node=None):  # 默认参数node=None
     12         self.__head = node           # 私有属性__head=>链表头
     13         if node:    # 如果存在node,需要设置回环
     14             node.next = node
     15 
     16     def is_empty(self):
     17         """判断链表是否为空"""
     18         return self.__head == None
     19 
     20     def length(self):
     21         """链表长度"""
     22         if self.is_empty():     # 如果是空链表,返回0
     23             return 0
     24         # cur初始时指向头节点,类似于游标,用来移动遍历节点
     25         cur = self.__head
     26         # 记录节点数量,初始为1,已经改变
     27         count = 1
     28         # 尾节点指向None,当未到达尾部时,循环结束
     29         while cur.next != self.__head:      # 循环条件变了
     30             count += 1
     31             # 将cur后移一个节点
     32             cur = cur.next
     33         return count
     34 
     35     def travel(self):
     36         """遍历链表"""
     37         if self.is_empty():
     38             return
     39         cur = self.__head
     40         while cur.next != self.__head:
     41             print(cur.elem, end=" ")    # 打印元素的值
     42             cur = cur.next              # cur后移
     43         # 退出循环,cur指向尾节点,但尾节点的元素未打印
     44         print(cur.elem, end=" ")
     45         print("")   # 换行
     46 
     47     def add(self, item):
     48         """头部添加元素,头插法"""
     49         # 先创建一个保存item值的节点
     50         node = Node(item)
     51         if self.is_empty():     # 如果链表为空
     52             self.__head = node
     53             node.next = node
     54         else:
     55             cur = self.__head
     56             while cur.next != self.__head:
     57                 cur = cur.next
     58             # 退出循环,cur指向尾节点
     59             node.next = self.__head
     60             self.__head = node
     61             cur.next = self.__head      # <==>cur.next = node
     62 
     63     def append(self, item):
     64         """尾部添加元素,尾插法"""
     65         node = Node(item)
     66         # 先判断链表是否为空,若是空链表,则将__head指向新节点
     67         if self.is_empty():
     68             self.__head = node
     69             node.next = node
     70         # 若不为空,则找到尾部,将尾节点的next指向新节点
     71         else:
     72             cur = self.__head
     73             while cur.next != self.__head: #此时循环条件变了
     74                 cur = cur.next
     75             node.next = self.__head     # <==>node.next = cur.next
     76             cur.next = node
     77 
     78     def insert(self, pos, item):
     79         """指定位置添加元素
     80         : param   pos 从0开始
     81         """
     82         # 若指定位置pos为第一个元素之前,则执行头部插入
     83         if pos <= 0:
     84             self.add(item)
     85         # 若指定位置超过链表尾部,则执行尾部插入
     86         elif pos > (self.length()-1):   # 不能包含等号=
     87             self.append(item)
     88         # 找到指定位置
     89         else:
     90             node = Node(item)
     91             count = 0
     92             # pre用来指向指定位置pos的前一个位置pos-1,初始从头节点开始移动到指定位置
     93             pre = self.__head
     94             while count < (pos-1):
     95                 count += 1
     96                 pre = pre.next      # 循环结束后,pre指向pos-1位置
     97             # 先将新节点node的next指向插入位置的节点
     98             node.next = pre.next
     99             # 将插入位置的前一个节点的next指向新节点
    100             pre.next = node
    101 
    102     def remove(self, item):
    103         """删除节点"""
    104         if self.is_empty():
    105             return
    106         cur = self.__head
    107         pre = None
    108         while cur.next != self.__head:
    109             # 找到了指定元素
    110             if cur.elem == item:
    111                 # 先判断此节点是否是头结点
    112                 # 如果第一个就是删除的节点
    113                 if cur == self.__head:      # 头节点
    114                     # 找尾节点,重新定义一个游标rear,标记尾节点
    115                     rear = self.__head
    116                     while rear.next != self.__head:
    117                         rear = rear.next
    118                     self.__head = cur.next
    119                     rear.next = self.__head
    120                 else:                       # 中间节点
    121                     # 将删除位置前一个节点的next指向删除位置的后一个节点
    122                     pre.next = cur.next
    123                 return
    124             else:
    125                 # 继续按链表后移节点,注意移动的先后顺序
    126                 pre = cur
    127                 cur = cur.next
    128         # 退出循环,cur指向尾节点
    129         if cur.elem == item:
    130             if cur == self.__head:
    131                 self.__head = None
    132             else:
    133                 pre.next = cur.next
    134 
    135     def search(self, item):
    136         """链表查找节点是否存在,并返回True或者False"""
    137         if self.is_empty():
    138             return False
    139         cur = self.__head
    140         while cur.next != self.__head:
    141             if cur.elem == item:
    142                 return True
    143             else:
    144                 cur = cur.next
    145         if cur.elem == item:
    146             return True
    147         return False
    148 
    149 if __name__ == "__main__":
    150     ll = SingleCycleLinkList()
    151     print(ll.is_empty())    # True
    152     print(ll.length())      # 0
    153 
    154     ll.append(1)
    155     print(ll.is_empty())    # False
    156     print(ll.length())      # 1
    157 
    158     ll.append(2)
    159     ll.add(8)
    160     ll.append(3)
    161     ll.append(4)
    162     ll.append(5)
    163     ll.append(6)
    164     ll.travel()         # 8 1 2 3 4 5 6
    165 
    166     ll.insert(-1, 9)
    167     ll.travel()         # 9 8 1 2 3 4 5 6
    168     ll.insert(3, 100)
    169     ll.travel()         # 9 8 1 100 2 3 4 5 6
    170     ll.insert(10, 200)
    171     ll.travel()         # 9 8 1 100 2 3 4 5 6 200
    172     ll.remove(100)
    173     ll.travel()         # 9 8 1 2 3 4 5 6 200
    174     ll.remove(9)
    175     ll.travel()         # 8 1 2 3 4 5 6 200
    176     ll.remove(200)
    177     ll.travel()         # 8 1 2 3 4 5 6

    (4)运行结果:

        

    文章写来不易,转载请标注。。。欢迎关注!
  • 相关阅读:
    构建之法 阅读笔记01
    个人作业1 -数组
    进度一
    开课博客
    生活尝试
    人月神话3
    安卓开发工具
    人月神话 2
    Qt 的入门小程序
    提问的智慧 摘抄(How To Ask Questions The Smart Way)
  • 原文地址:https://www.cnblogs.com/si-lei/p/9262471.html
Copyright © 2020-2023  润新知