-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinklist.py
343 lines (290 loc) · 9.14 KB
/
linklist.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
__all__ = ["SingleLinkList", "SingleCycleLinkList", "DoubleLinkList"]
class SingleNode(object):
"""单链表节点"""
def __init__(self, elem):
self.elem = elem
self.next = None
class DoubleNode(SingleNode):
"""双链表节点"""
def __init__(self, elem):
self.prev = None
super().__init__(elem)
class _LinkedList(object):
"""抽象抽象类,只用于被继承,不能实例化"""
def __init__(self):
self.head = None
def __str__(self, end=" -> "):
"""遍历输出整个链表"""
cur = self.head
elems = []
while cur != None:
elems.append(str(cur.elem))
cur = cur.next
return end.join(elems)
def is_empty(self):
"""链表是否为空"""
return self.head == None
def length(self):
"""链表长度"""
# cur游标,用来移动遍历节点
cur = self.head
# count记录数量
count = 0
while cur != None:
count += 1
cur = cur.next
return count
def prepend(self, item):
"""链表头部添加元素(头插法)"""
pass
def append(self, node):
"""链表尾部添加元素(尾插法)"""
if self.is_empty():
self.head = node
return None
cur = self.head
while cur.next != None:
cur = cur.next
cur.next = node
return cur
def insert(self, position, item, is_double=False):
"""指定位置添加元素
:param position 从0开始
"""
if position <= 0:
self.add(item)
elif position > (self.length() - 1):
self.append(item)
else:
if is_double:
return True
# 以下单链表和单向循环链表插入逻辑
pre = self.head
count = 0
while count < (position - 1):
count += 1
pre = pre.next
# 当循环退出后,pre指向position-1位置
node = SingleNode(item)
node.next = pre.next
pre.next = node
def remove(self, item):
"""删除节点"""
pass
def contains(self, item):
"""判断节点是否存在"""
cur = self.head
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
class SingleLinkList(_LinkedList):
"""单链表"""
def prepend(self, item):
"""链表头部添加元素(头插法)"""
node = SingleNode(item)
node.next = self.head
self.head = node
def append(self, item):
"""链表尾部添加元素(尾插法)"""
node = SingleNode(item)
super().append(node)
def insert(self, position, item):
"""指定位置添加元素
:param position 从0开始
"""
super().insert(position, item)
def remove(self, item):
"""删除节点"""
cur = self.head
pre = None
while cur != None:
if cur.elem == item:
# 先判断此结点是否是头节点
# 头节点
if cur == self.head:
self.head = cur.next
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
class SingleCycleLinkList(_LinkedList):
"""单向循环链表"""
def length(self):
"""链表长度"""
if self.is_empty():
return 0
# cur游标,用来移动遍历节点
cur = self.head
# count记录数量
count = 1
while cur.next != self.head:
count += 1
cur = cur.next
return count
def __str__(self):
"""遍历输出整个链表"""
if self.is_empty():
return ""
cur = self.head
first, elems = str(cur.elem) + "(head)", []
while cur.next != self.head:
elems.append(str(cur.elem))
cur = cur.next
# 退出循环,cur指向尾节点,但尾节点的元素未打印
elems.append(str(cur.elem))
elems.append(first)
return " -> ".join(elems)
def prepend(self, item):
"""链表头部添加元素(头插法)"""
node = SingleNode(item)
if self.is_empty():
self.head = node
node.next = node
else:
cur = self.head
while cur.next != self.head:
cur = cur.next
# 退出循环,cur指向尾节点
node.next = self.head
self.head = node
# cur.next = node
cur.next = self.head
def append(self, item):
"""链表尾部添加元素(尾插法)"""
node = SingleNode(item)
if self.is_empty():
self.head = node
node.next = node
else:
cur = self.head
while cur.next != self.head:
cur = cur.next
# node.next = cur.next
node.next = self.head
cur.next = node
def insert(self, position, item):
"""指定位置添加元素
:param position 从0开始
"""
super().insert(position, item)
def remove(self, item):
"""删除节点"""
if self.is_empty():
return
cur = self.head
pre = None
while cur.next != self.head:
if cur.elem == item:
# 先判断此结点是否是头节点
if cur == self.head:
# 头节点的情况
# 找尾节点
rear = self.head
while rear.next != self.head:
rear = rear.next
self.head = cur.next
rear.next = self.head
else:
# 中间节点
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
# 退出循环,cur指向尾节点
if cur.elem == item:
if cur == self.head:
# 链表只有一个节点
self.head = None
else:
# pre.next = cur.next
pre.next = self.head
def contains(self, item):
"""判断节点是否存在"""
if self.is_empty():
return False
cur = self.head
while cur.next != self.head:
if cur.elem == item:
return True
else:
cur = cur.next
# 退出循环,cur指向尾节点
if cur.elem == item:
return True
return False
class DoubleLinkList(_LinkedList):
"""双链表"""
def __str__(self):
return super().__str__(" <-> ")
def prepend(self, item):
"""链表头部添加元素(头插法)"""
node = DoubleNode(item)
node.next = self.head
self.head = node
node.next.prev = node
def append(self, item):
"""链表尾部添加元素(尾插法)"""
node = DoubleNode(item)
cur = super().append(node)
if cur:
node.prev = cur
def insert(self, position, item):
"""指定位置添加元素
:param position 从0开始
"""
valid = super().insert(position, item, True)
if valid:
cur = self.head
count = 0
while count < position:
count += 1
cur = cur.next
# 当循环退出后,cur指向position位置
node = DoubleNode(item)
node.next = cur
node.prev = cur.prev
cur.prev.next = node
cur.prev = node
def remove(self, item):
"""删除节点"""
cur = self.head
while cur != None:
if cur.elem == item:
# 先判断此结点是否是头节点
# 头节点
if cur == self.head:
self.head = cur.next
if cur.next:
# 判断链表是否只有一个结点
cur.next.prev = None
else:
cur.prev.next = cur.next
if cur.next:
cur.next.prev = cur.prev
break
else:
cur = cur.next
if __name__ == '__main__':
def test_linklist(linklist):
def print_linklist_status(ll):
print(
"is_empty:%s\tlength:%s\t\r\nelements:%s\r\n" % (ll.is_empty(), ll.length(), str(ll)))
print("-" * 15 + str(linklist.__class__) + "-" * 15)
print_linklist_status(linklist)
linklist.append(1)
linklist.prepend(0)
print_linklist_status(linklist)
linklist.insert(1, 10)
print("contains:%s" % linklist.contains(10))
print_linklist_status(linklist)
linklist.remove(10)
print_linklist_status(linklist)
test_linklist(SingleLinkList())
test_linklist(SingleCycleLinkList())
test_linklist(DoubleLinkList())