Python单链表实现list一样的功能
知识点:链表,魔法方法,迭代器,排序,内置函数
class LinkedList():
class Node():
def __init__(self, item):
self.item = item
self.next = None
def __init__(self):
self.head = None
self.__length = 0
def headadd(self, item):
"""头部插入数据,list中没有的方法
"""
new_node = self.Node(item)
if self.head == None:
self.head = new_node
else:
new_node.next = self.head
self.head = new_node
def append(self, item):
p = self.head
new_node = self.Node(item)
if p == None:
self.head = new_node
self.__length += 1
return
while p:
if p.next == None:
p.next = new_node
self.__length += 1
return
p = p.next
def insert(self, index, item):
if index >= self.__length:
self.append(item)
return
elif index <= 0:
new_node = self.Node(item)
new_node.next = self.head
self.head = new_node
else:
new_node = self.Node(item)
p = self.head
count = 0
while p:
if count == index - 1:
new_node.next = p.next
p.next = new_node
break
p = p.next
count += 1
self.__length += 1
def pop(self, index):
if index < -self.__length or index >= self.__length:
raise IndexError("pop index out of range")
elif index == 0 or index == -self.__length:
item = self.head.item
self.head = self.head.next
self.__length -= 1
return item
else:
if index < 0:
index = self.__length + index
p = self.head
count = 0
while p:
if count == index - 1:
item = p.next.item
p.next = p.next.next
self.__length -= 1
return item
else:
p = p.next
count += 1
def sort(self, start=None, stop=None, reverse=False):
if start == None:
start = 0
if stop == None:
stop = self.__length-1
left = start
right = stop
if right <= left:
return
mid = self[left]
while right > left:
while self[right] >= mid and right>left:
right -= 1
if right>left:
self[left] = self[right]
else:
self[right] = mid
break
while self[left] <= mid and left < right:
left += 1
if left < right:
self[right] = self[left]
else:
self[left] = mid
break
self.sort(start, left-1)
self.sort(right+1, stop)
if reverse:
p = self.head
temp = None
while p:
next = p.next
p.next = temp
temp = p
p = next
self.head = temp
def __getitem__(self, index):
"""当使用[]索引获取对象时的行为,例如 a[1]
"""
if isinstance(index, int):
if index >= self.__length or index < -self.__length:
raise IndexError("index out of range")
else:
p = self.head
if index < 0:
index = self.__length + index
for i in range(index):
p = p.next
return p.item
elif isinstance(index, slice):
""" slice对象有三个属性,start,stop,step
"""
start = index.start if index.start != None else 0
stop = index.stop if index.stop != None else self.__length
step = index.step if index.step != None else 1
if not (isinstance(start, int) and isinstance(stop, int) and isinstance(step, int)):
raise TypeError('type of index error;please input int type.')
if start < 0:
start = 0 if start <= -self.__length else self.__length + start
if stop < 0:
stop = 0 if stop <= -self.__length else self.__length + stop
if step < 0 and start >= stop:
start, stop = stop, start
p = self.head
new_list = LinkedList()
count = 0
while p:
new_node = self.Node(p.item)
if start <= count < stop:
if start == count:
new_p = new_list.head = new_node
else:
if step > 0:
new_p.next = new_node
new_p = new_p.next
else:
new_node.next = new_list.head
new_list.head = new_node
elif count >= stop:
return new_list
for i in range(abs(step)):
p = p.next
count += 1
return new_list
else:
raise TypeError("type of index error")
def __delitem__(self, key):
"""当按照[]下标索引使用del方法删除元素时,触发此函数, 例如 del a[1]
若 不重写次函数,则会报异常 AttributeError: __delitem__
"""
if not isinstance(key, int):
raise TypeError("type of key error")
if key < - self.__length or key >= self.__length:
raise IndexError("index out of range")
self.pop(key)
def __setitem__(self, index, item):
"""当使用[]索引对元素赋值的行为, 例如 a[0]=2
"""
if isinstance(index, int):
if index < -self.__length or index >= self.__length:
raise IndexError("index out of range")
else:
p = self.head
if index < 0:
index = self.__length + index
for i in range(index):
p = p.next
p.item = item
else:
raise Exception("type of index error")
def __contains__(self, item):
for each in self:
if each == item:
return True
else:
return False
def __add__(self, right_list):
""" 当调用 + 法的行为, 如果未调用此方法则会报异常(TypeError)
"""
temp = LinkedList()
for each in self:
temp.append(each)
for each in right_list:
temp.append(each)
return temp
def __len__(self):
"""当对该对象使用len()函数时触发此函数
"""
return self.__length
def __iter__(self):
"""当对该对象使用 iter()函数时触发此函数,返回一个迭代器。实现了迭代器,则可以调用list/tuple/set方法与容器对象进行类型转换。
与__next__方法搭配使用
"""
if not hasattr(self, '_p_list'):
setattr(self, '_p_list', [self.head])
else:
self._p_list.append(self.head)
return self
def __next__(self):
"""当对生成器使用next()方法时触发此函数,与__iter__函数搭配使用,要使用StopIteration异常作为结束条件
"""
p = self._p_list[-1]
if p:
item = p.item
self._p_list[-1] = p.next
return item
else:
del self._p_list[-1]
raise StopIteration
def __str__(self):
"""当使用print()打印时的动作
"""
string = ''
for each in self:
string += str(each) + '->'
return string if string else '->'
if __name__ == '__main__':
a = LinkedList()
import random
r = [random.randint(0, 20) for i in range(10)]
for i in r:
a.append(i)
print('排序测试:')
print(a)
a.sort()
print(a)
a.sort(reverse=True)
print(a)
print('del 函数测试')
del a[0]
print(a)
print('切片测试')
b = a[2:5:]
print(b)
print('for 语句测试')
for each in a:
print(a)
print()
for each in a:
print(each, end='->')
print()
print('[]索引赋值测试:')
a[-1] = 100
print(a)
排序测试:
16->4->15->1->20->7->5->15->2->3->
1->2->3->4->5->7->15->15->16->20->
20->16->15->15->7->5->4->3->2->1->
del 函数测试
16->15->15->7->5->4->3->2->1->
切片测试
15->7->5->
for 语句测试
16->15->15->7->5->4->3->2->1->
16->15->15->7->5->4->3->2->1->
16->15->15->7->5->4->3->2->1->
16->15->15->7->5->4->3->2->1->
16->15->15->7->5->4->3->2->1->
16->15->15->7->5->4->3->2->1->
16->15->15->7->5->4->3->2->1->
16->15->15->7->5->4->3->2->1->
16->15->15->7->5->4->3->2->1->
16->15->15->7->5->4->3->2->1->
[]索引赋值测试:
16->15->15->7->5->4->3->2->100->