4. 单向循环链表

Posted si-lei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)运行结果:

    技术分享图片

以上是关于4. 单向循环链表的主要内容,如果未能解决你的问题,请参考以下文章

单向循环链表

java实现单向循环链表

(java实现)单向循环链表

java-----循环链表

java-----循环链表

python中的单向循环链表实现