将对象存储在列表中
将对象存储在列表中,这样就将双链表封装为容器
提供像操作列表一样的功能
- 设置__getitem__属性,满足像访问list[key]一样访问
- 设置__iter__属性,使得实例就像一个迭代器一样,从队列中跌倒出元素
- 设置__setitem__属性,满足像操作列表一样设置值,list[index] = value
代码实现
#-*- coding=UTF-8 -*-
import random
class Nodes:
"""no doc"""
def __init__(self,value,previous=None,next=None):
self.value = value
self._next = next
self._previous = previous
class LinkList:
"""no doc"""
def __init__(self,head=None,tail=None):
self.head = head
self.tail = tail
self._length = 0
self.list = []
def __str__(self):
string = str([x for x in self.iternodes()]).strip("[]")
return "<{}>".format(string)
def __len__(self):
return self._length
def __getitem__(self,item):
return self.list[item].value
def __iter__(self):
return (x.value for x in self.list)
def __setitem__(self, index, value):
self.list[index].value = value
def append(self,value):
"""
:param value: 添加的元素
:return: None
"""
node = Nodes(value)
obj = self.head
if self.head == None:
self.head = node
self.tail = node
self._length += 1
self.list.append(node)
else:
# 找最后一个元素
while True:
if obj._next != None:
obj = obj._next
else:
#第一个元素的next属性指向新增node实例
obj._next = node
#新增实例的previous属性指向之前的实例
node._previous = obj
#每次新增元素,更新self.tail元素
self.tail = node
self._length += 1
self.list.append(node)
break
def pop(self):
"""no doc"""
obj = self.head
elementnum = 0
index = random.randint(0,len(self)-1)
self.list.pop(index)
while elementnum < index:
obj = obj._next
elementnum += 1
#边界进行处理
if obj._next == None : #随机是最后一个元素时的动作
obj._previous._next = None
self._length -= 1
elif obj._previous == None: #随机是第一个元素时的动作
obj._next._previous = None
self.head = obj._next
self._length -= 1
else:
obj._previous._next = obj._next
obj._next._previous = obj._previous
self._length -= 1
def insert(self,index,value):
"""no doc insert"""
obj = self.head
elementnum = 0
if index > len(self)-1:
print("out of index")
return "out of index"
while elementnum < index-1:
obj = obj._next
elementnum += 1
node = Nodes(value)
#修改元素属性
if index == 0: #边界处理,当插入位置为第一个位置时的动作
self.head._previous = node
node._next = self.head
self.head = node
self._length += 1
self.list.insert(index,node)
else:
obj._next._previous = node
node._next =obj._next
obj._next = node
node._previous = obj
self._length += 1
self.list.insert(index,node)
def remove(self,value):
"""no doc"""
obj = self.head
self.list.remove(value)
while True:
if obj.value != value:
obj = obj._next
continue
elif obj.value == self.head.value:
obj._next._previous = None
self.head = obj._next
self._length -= 1
del obj
elif obj.value == self.tail.value:
obj._previous._next = None
self.tail = obj._previous
self._length -= 1
else:
#删除对象前一个元素的next指向下一个元素
obj._previous._next = obj._next
obj._next._previous = obj._previous
self._length -= 1
del obj
break
def iternodes(self):
"""
从头开始跌代,不能回头
:return: None
"""
obj = self.head
while True:
if obj == None:
break
else:
yield obj.value
obj = obj._next
link = LinkList()
link.append(5)
link.append(6)
link.append(7)
link.append(8)
link.insert(3,10)
print(link)
link[2]=100
print(link)
运行结果:
<5, 6, 7, 10, 8>
<5, 6, 100, 10, 8>