單向:
class Node:
def __init__(self,value,next=None,pre=None):#Todo DoubleLinklist
self.val = value
self.next = next
self.pre = pre
def __str__(self):
return self.val
class Linkedlist:
def __init__(self):
self.nodes = [] # 對於不需要插入的列表來說,檢索方便,但是如果需要插入,remove卻不合適
self.head = None
self.tail = None
def append(self,value):
node = Node(value)
if self.tail == None:
self.head = node
self.tail = node
else:
self.tail.next = node
self.nodes.append(node)
self.tail = node
def iternodes(self,reversed=False): #Todo DoubleLinklist
while self.head:
yield self.head
self.head = self.head.next
def __getitem__(self, item):
return self.nodes[item]
def __len__(self):
return len(self.nodes)
ll = Linkedlist()
ll.append('a')
ll.append('b')
gn = ll.iternodes()
print(type(gn))
for i in gn:
print(i)
print(ll[1])# __getitem__實現的功能
print(len(ll))# __len__實現的功能
運行結果:
<class 'generator'>
a # __str__實現的功能
b # __str__實現的功能
b # __getitem__實現的功能
2 # __len__實現的功能
雙向:
class SingleNode:
'''代表一個節點'''
def __init__(self,val,next=None,prev=None):
self.val = val #node實例值
self.next = next #node對象
self.prev = prev #node對象
def __str__(self):
return str(self.val)
def __repr__(self):
return str(self.val)
class Linkedlist:
'''容器類,某種方式存儲一個個節點'''
def __init__(self):
self.head = None
self.tail = None
def append(self,val):
node = SingleNode(val)
if self.head is None:
self.head = node
else:
node.prev = self.tail
self.tail.next = node
self.tail = node
def iternodes(self,reverse=False):
current = self.tail if reverse else self.head
while current:
yield current
current = current.prev if reverse else current.next
def pop(self):
if self.tail is None:
raise Exception('Empty')
tail = self.tail
prev = tail.prev
if prev is None:
self.head = None
self.tail = None
else:
self.tail = prev
prev.next = None
return tail.val
def getitem(self,index):
if index < 0:
return None
current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is not None:
return current
def insert(self,index,val):
if index < 0:
raise Exception('Error')
current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is None:
self.append(val)
return
prev = current.prev
node = SingleNode(val)
if prev is None:
self.head = node
current.prev = node
node.next = current
else:
node.prev = prev
node.next = current
current.prev = node
prev.next = node
ll = Linkedlist()
node = SingleNode(1)
ll.append(node)
node = SingleNode(2)
ll.append(node)
node = SingleNode(3)
ll.append(node)
node = SingleNode('abc')#用於pop測試
ll.append(node)
ll.pop()
ll.insert(4,4)
ll.insert(5,5)
for node in ll.iternodes(reverse=True):
print(node)
print(ll.getitem(0))
運行結果:
5
4
3
2
1
1
容器化的解決
from functools import partial
class SingleNode:
'''代表一個節點'''
def __init__(self,val,next=None,prev=None):
self.val = val #node實例值
self.next = next #node對象
self.prev = prev #node對象
def __str__(self):
return str(self.val)
def __repr__(self):
return str(self.val)
class Linkedlist:
'''容器類,某種方式存儲一個個節點'''
def __init__(self):
self.head = None
self.tail = None
self.size = 0
self.list = []
def append(self,val):
node = SingleNode(val)
if self.head is None:
self.head = node
else:
node.prev = self.tail
self.tail.next = node
self.tail = node
self.size += 1
#列表操作
self.list.append(node)
def pop(self):
if self.tail is None:
raise Exception('Empty')
tail = self.tail
prev = tail.prev
if prev is None:
self.head = None
self.tail = None
else:
self.tail = prev
prev.next = None
self.size -= 1
#列表操作
self.list.pop()
return tail.val
def getitem(self,index):
if index < 0:
return None
current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is not None:
print(current.val)
else:
raise IndexError('Out of range')
# return self.list[index].val
def setitem(self,index,value):
if index < 0:
return None
current = None
for i, node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is not None:
current.val = value
return current.val
def insert(self,index,val):
if index < 0:
raise Exception('Error')
current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is None:
self.append(val)
return
prev = current.prev
node = SingleNode(val)
if prev is None:
self.head = node
else:
node.prev = prev
prev.next = node
node.next = current
current.prev = node
self.list.insert(index,node)
def remove(self,index):
if self.tail is None:
raise Exception('Empty')
if index < 0:
raise ValueError('Wrong Index{}'.format(index))
current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is None:
raise ValueError('Wrong Index {} ,Out of boundary'.format(index))
prev = current.prev
next = current.next
if prev is None and next is None:
self.head = None
self.tail = None
elif prev is None:
self.head = index
next.prev = None
elif next is None:
self.tail = prev
prev.next = None
else:
prev.next = next
next.prev = prev
del current
self.size -= 1
return self.list.pop(index)
def iternodes(self, reverse=False):
current = self.tail if reverse else self.head
while current:
yield current
current = current.prev if reverse else current.next
def __len__(self):
return len(self.list)
def __getitem__(self, index): # 如果沒有__iter__則調用此方法進行迭代
print(self.list[index].val)
def __setitem__(self, index, value):
self.list[index].val = value
# def __iter__(self):
# return self.iternodes(reverse=True)
# def __iter__(self):
# iternodes = partial(self.iternodes,reverse=True)
# return iternodes()
# __iter__ = lambda self:self.iternodes(reverse=False)
__iter__ = lambda self:partial(self.iternodes,reverse=True)()
#增
ll = Linkedlist()
ll.append(123)
ll.append(456)
ll.append(789)
ll[0]
ll[1]
ll[2]
ll.getitem(0)
ll.getitem(1)
ll.getitem(2)
print('====================================')
print(type(ll.iternodes()))
for i in ll.iternodes():
print(i)
print('====================================')
ll[0] = 'a'
ll.setitem(1,'b')
ll.setitem(2,'c')
ll[0]
ll[1]
ll[2]
ll.getitem(0)
ll.getitem(1)
ll.getitem(2)
print('====================================')
print(type(ll.iternodes()))
for i in ll.iternodes():
print(i)
print('====================================')
#刪--pop
print('popvalue = ',ll.pop())
for i in ll.iternodes():
print(i)
#刪--remove
print('removevalue = ',ll.remove(1))
for i in ll.iternodes():
print(i)
print('====================================')
#改
ll.setitem(0,'hello')
ll.append('the')
ll.insert(2,'world')
ll.getitem(0)
ll[1]
ll[2]
ll[2] = 'world!!!'
for i in ll.iternodes():
print(i)
print('====================================')
#查
ll[0]
ll.getitem(1)
print(len(ll))
print('====================================')
print(type(ll))
for i in ll: #省略了.iternodes()
print(i)
print(ll.size)
print('====================================')
print(ll.__dict__)
print(Linkedlist.__dict__)
運行結果:
123
456
789
123
456
789
====================================
<class 'generator'>
123
456
789
====================================
a
b
c
a
b
c
====================================
<class 'generator'>
a
b
c
====================================
popvalue = c
a
b
removevalue = b
a
====================================
hello
the
world
hello
the
world!!!
====================================
hello
the
3
====================================
<class '__main__.Linkedlist'>
world!!!
the
hello
3
====================================
{'size': 3, 'head': hello, 'tail': world!!!, 'list': [hello, the, world!!!]}
{'__getitem__': <function Linkedlist.__getitem__ at 0x7f6f6cd9ef28>, '__len__': <function Linkedlist.__len__ at 0x7f6f6cd9eea0>, 'remove': <function Linkedlist.remove at 0x7f6f6cd9ed90>, '__dict__': <attribute '__dict__' of 'Linkedlist' objects>, 'insert': <function Linkedlist.insert at 0x7f6f6cd9ed08>, 'getitem': <function Linkedlist.getitem at 0x7f6f6cd9ebf8>, '__module__': '__main__', '__iter__': <function Linkedlist.<lambda> at 0x7f6f6cdaa0d0>, '__doc__': '容器類,某種方式存儲一個個節點', 'setitem': <function Linkedlist.setitem at 0x7f6f6cd9ec80>, 'iternodes': <function Linkedlist.iternodes at 0x7f6f6cd9ee18>, 'append': <function Linkedlist.append at 0x7f6f6cd9eae8>, 'pop': <function Linkedlist.pop at 0x7f6f6cd9eb70>, '__init__': <function Linkedlist.__init__ at 0x7f6f6cd9ea60>, '__weakref__': <attribute '__weakref__' of 'Linkedlist' objects>, '__setitem__': <function Linkedlist.__setitem__ at 0x7f6f6cdaa048>}
非容器化解決上述增刪改查
from functools import partial
class SingleNode:
'''代表一個節點'''
def __init__(self,val,next=None,prev=None):
self.val = val #node實例值
self.next = next #node對象
self.prev = prev #node對象
def __str__(self):
return str(self.val)
def __repr__(self):
return str(self.val)
class Linkedlist:
'''容器類,某種方式存儲一個個節點'''
def __init__(self):
self.head = None
self.tail = None
self.size = 0
def append(self,val):
node = SingleNode(val)
if self.head is None:
self.head = node
else:
node.prev = self.tail
self.tail.next = node
self.tail = node
self.size += 1
def pop(self):
if self.tail is None:
raise Exception('Empty')
tail = self.tail
prev = tail.prev
if prev is None:
self.head = None
self.tail = None
else:
self.tail = prev
prev.next = None
self.size -= 1
return tail.val
def insert(self,index,val):
if index < 0:
raise Exception('Error')
current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is None:
self.append(val)
return
prev = current.prev
node = SingleNode(val)
if prev is None:
self.head = node
else:
node.prev = prev
prev.next = node
node.next = current
current.prev = node
def remove(self,index):
if self.tail is None:
raise Exception('Empty')
if index < 0:
raise ValueError('Wrong Index{}'.format(index))
current = None
for i,node in enumerate(self.iternodes()):
if i == index:
current = node
break
if current is None:
raise ValueError('Wrong Index {} ,Out of boundary'.format(index))
prev = current.prev
next = current.next
if prev is None and next is None:
self.head = None
self.tail = None
elif prev is None:
self.head = index
next.prev = None
elif next is None:
self.tail = prev
prev.next = None
else:
prev.next = next
next.prev = prev
del current
self.size -= 1
def iternodes(self, reverse=False):
current = self.tail if reverse else self.head
while current:
yield current
current = current.prev if reverse else current.next
def __len__(self):
return self.size
def __getitem__(self, index): # 如果沒有__iter__則調用此方法進行迭代
for i,node in enumerate(self.iternodes(False if index >=0 else True),0 if index >=0 else 1):
if i == abs(index):
return node
def __setitem__(self, index, value):
self[index].val = value
__iter__ = lambda self:partial(self.iternodes,reverse=True)()
#增
ll = Linkedlist()
ll.append(123)
ll.append(456)
ll.append(789)
print(ll[0])
print(ll[1])
print(ll[2])
print('====================================')
print(type(ll.iternodes()))
for i in ll.iternodes():
print(i)
print('====================================')
ll[0] = 'a'
print(ll[0])
print(ll[1])
print(ll[2])
print('====================================')
print(type(ll))
for i in ll:
print(i)
print('====================================')
#刪--pop
print('popvalue = ',ll.pop())
for i in ll.iternodes():
print(i)
#刪--remove
print('removevalue = ',ll.remove(1))
for i in ll.iternodes():
print(i)
print('====================================')
#改
ll.append('the')
ll.insert(2,'world')
print(ll[0])
print(ll[1])
ll[2] = 'world!!!'
for i in ll:
print(i)
print('====================================')
#查
print(ll[0])
print(len(ll))
print('====================================')
print(type(ll))
for i in ll: #省略了.iternodes()
print(i)
print(ll.size)
print('====================================')
print(ll.__dict__)
print(Linkedlist.__dict__)
運行結果:
123
456
789
====================================
<class 'generator'>
123
456
789
====================================
a
456
789
====================================
<class '__main__.Linkedlist'>
789
456
a
====================================
popvalue = 789
a
456
removevalue = None
a
====================================
a
the
world!!!
the
a
====================================
a
3
====================================
<class '__main__.Linkedlist'>
world!!!
the
a
3
====================================
{'tail': world!!!, 'size': 3, 'head': a}
{'pop': <function Linkedlist.pop at 0x7ffb91ac9bf8>, '__len__': <function Linkedlist.__len__ at 0x7ffb91ac9e18>, '__getitem__': <function Linkedlist.__getitem__ at 0x7ffb91ac9ea0>, '__dict__': <attribute '__dict__' of 'Linkedlist' objects>, 'iternodes': <function Linkedlist.iternodes at 0x7ffb91ac9d90>, '__doc__': '容器類,某種方式存儲一個個節點', '__init__': <function Linkedlist.__init__ at 0x7ffb91ac9ae8>, '__weakref__': <attribute '__weakref__' of 'Linkedlist' objects>, '__module__': '__main__', '__setitem__': <function Linkedlist.__setitem__ at 0x7ffb91ac9f28>, '__iter__': <function Linkedlist.<lambda> at 0x7ffb91ad5048>, 'insert': <function Linkedlist.insert at 0x7ffb91ac9c80>, 'remove': <function Linkedlist.remove at 0x7ffb91ac9d08>, 'append': <function Linkedlist.append at 0x7ffb91ac9b70>}