classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueclassFavoritesList:"""List of elements ordered from most frequently accessed to least."""# ---------------nested _Item class ----------class_Item:
__slots__ ="_value","_count"# streamling memory usagedef__init__(self, e):
self._value = e # the user's element
self._count =0# access count initially zero# --------nonpublic utilities -------------------------def_find_position(self, e):"""Search for element e and return its Position(or None if not found)."""
walk = self._data.first()while walk isnotNoneand walk.element()._value != e:
walk = self._data.after(walk)return walk
def_move_up(self, p):"""Move item at Position p earlier in the list based on access count."""if p != self._data.first():
cnt = p.element()._count
walk = self._data.before(p)if cnt > walk.element()._count:# must shift forwardwhile walk != self._data.first()and cnt > self._data.before(walk).element()._count:
walk = self._data.before(walk)
self._data.add_before(walk, self._data.delete(p))# delete/reinsertdef__init__(self):"""Create an empty list of favorites."""
self._data = PositionalList()def__len__(self):"""Return number of entries on favorites list"""returnlen(self._data)defis_empty(self):"""Return True if list is empty."""returnlen(self._data)==0defaccess(self, e):"""Access element e,thereby increasing its access count."""
p = self._find_position(e)# try to locate existing elementif p isNone:
p = self._data.add_last(self._Item(e))# if new ,place at end
p.element()._count +=1# always increment count
self._move_up(p)# consider moving forwarddefremove(self, e):"""Remove element e from the list of favorites."""
p = self._find_position(e)# try to locate existing elementif p isnotNone:
self._data.delete(p)# delete,if fountdeftop(self, k):"""Generate sequence of top k elements in terms of access count."""ifnot1<= k <=len(self):raise ValueError("Illegal value for k")
walk = self._data.first()for j inrange(k):
item = walk.element()# element of list is _Itemyield item._value # report user's element
walk = self._data.after(walk)defreversed(self):
walk = self._data.first()
temp = PositionalList()while walk isnotNone:
temp.add_first(walk.element())
walk = self._data.after(walk)
self._data = temp
defclear(self):iflen(self._data)==0:raise Empty("the favoritesList is empty")
walk = self._data
whilelen(walk)!=0:
walk.delete(walk.first())if __name__ =="__main__":
favoritelist = FavoritesList()
favoritelist.access('a')
favoritelist.access('b')
favoritelist.access('c')
favoritelist.clear()print(len(favoritelist))
23
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueclassFavoritesList:"""List of elements ordered from most frequently accessed to least."""# ---------------nested _Item class ----------class_Item:
__slots__ ="_value","_count"# streamling memory usagedef__init__(self, e):
self._value = e # the user's element
self._count =0# access count initially zero# --------nonpublic utilities -------------------------def_find_position(self, e):"""Search for element e and return its Position(or None if not found)."""
walk = self._data.first()while walk isnotNoneand walk.element()._value != e:
walk = self._data.after(walk)return walk
def_move_up(self, p):"""Move item at Position p earlier in the list based on access count."""if p != self._data.first():
cnt = p.element()._count
walk = self._data.before(p)if cnt > walk.element()._count:# must shift forwardwhile walk != self._data.first()and cnt > self._data.before(walk).element()._count:
walk = self._data.before(walk)
self._data.add_before(walk, self._data.delete(p))# delete/reinsertdef__init__(self):"""Create an empty list of favorites."""
self._data = PositionalList()def__len__(self):"""Return number of entries on favorites list"""returnlen(self._data)defis_empty(self):"""Return True if list is empty."""returnlen(self._data)==0defaccess(self, e):"""Access element e,thereby increasing its access count."""
p = self._find_position(e)# try to locate existing elementif p isNone:
p = self._data.add_last(self._Item(e))# if new ,place at end
p.element()._count +=1# always increment count
self._move_up(p)# consider moving forwarddefremove(self, e):"""Remove element e from the list of favorites."""
p = self._find_position(e)# try to locate existing elementif p isnotNone:
self._data.delete(p)# delete,if fountdeftop(self, k):"""Generate sequence of top k elements in terms of access count."""ifnot1<= k <=len(self):raise ValueError("Illegal value for k")
walk = self._data.first()for j inrange(k):
item = walk.element()# element of list is _Itemyield item._value,item._count # report user's element
walk = self._data.after(walk)defreversed(self):
walk = self._data.first()
temp = PositionalList()while walk isnotNone:
temp.add_first(walk.element())
walk = self._data.after(walk)
self._data = temp
defclear(self):iflen(self._data)==0:raise Empty("the favoritesList is empty")
walk = self._data
whilelen(walk)!=0:
walk.delete(walk.first())defreset_counts(self):
walk = self._data.first()while walk isnotNone:
walk.element()._count =0
walk = self._data.after(walk)passif __name__ =="__main__":
favoritelist = FavoritesList()
favoritelist.access('a')
favoritelist.access('b')
favoritelist.access('c')
favoritelist.access('c')
favoritelist.access('d')
favoritelist.access('a')
favoritelist.access('a')
favoritelist.access('a')
favoritelist.access('b')
favoritelist.access('b')for key,value in favoritelist.top(3):print(key,value)
favoritelist.reset_counts()for key,value in favoritelist.top(3):print(key,value)
24
classEmpty(Exception):passclassStack:
__slots__ ="_header","_size"class_Node:
__slots__ ="_next","_element"def__init__(self, value,next):
self._element = value
self._next =nextdef__init__(self):
self._size =0
self._header = self._Node(None,None)def__len__(self):return self._size
defis_empty(self):return self._size ==0deftop(self):if self.is_empty():raise Empty('stack is None')return self._header._next._element
defpush(self, value):
self._header._next = self._Node(value, self._header._next)
self._size +=1defpop(self):if self.is_empty():raise Empty("stack is None")
temp = self._header._next
self._header._next = temp._next
value = temp._element
temp._next = temp._element =None
self._size -=1return value
if __name__ =="__main__":
stack = Stack()[stack.push(i)for i inrange(10)][print(stack.pop(), end=' ')for i inrange(10)]
25
classEmpty(Exception):passclassQueue:
__slots__ ="_header","_size"class_Node:
__slots__ ="_element","_next"def__init__(self, element,next):
self._element = element
self._next =nextdef__init__(self):
self._header = self._Node(None,None)
self._size =0def__len__(self):return self._size
defis_empty(self):return self._size ==0deffirst(self):if self.is_empty():raise Empty("queue is None")return self._header._next._element
defdequeue(self):if self.is_empty():raise Empty("queue is None")
temp = self._header._next
self._header._next = temp._next
value = temp._element
temp._next = temp._element =None
self._size -=1return value
defenqueue(self, value):
node = self._Node(value,None)
walk = self._header
whileTrue:if walk._next isNone:break
walk = walk._next
walk._next = node
self._size +=1if __name__ =="__main__":
queque = Queue()[queque.enqueue(i)for i inrange(10)][print(queque.dequeue(), end=' ')for i inrange(10)]
26
classEmpty(Exception):passclassLinkQueue:"""FIFO queue implementation using a singly linked list for storage."""
__slots__ ="_head","_tail","_size"class_Node:"""Lightweight,nonpublic class for storing a singly linked node."""
__slots__ ="_element","_next"# streamline memory usagedef__init__(self, element,next):# initialize node's fields
self._element = element # reference to user's element
self._next =next# reference to next nodedef__init__(self):"""Create an empty queue."""
self._head =None
self._tail =None
self._size =0# number of queue elementsdef__len__(self):"""Return the number of elements in the queue."""return self._size
defis_empty(self):"""Return True if the queue is emtpy."""return self._size ==0deffirst(self):"""Return (but do not remove) the element at the front of the queue."""if self.is_empty():raise Empty("Queue is empty")return self._head._element
defdequeue(self):"""Remove and return the first element of the queue.
Raise Emtpy exception if the queue is empty.
"""if self.is_empty():raise Empty("Queue is empty")
answer = self._head._element
self._head = self._head._next
self._size -=1if self.is_empty():# special case as queue is empty
self._tail =None# remove head had been the tailreturn answer
defenqueue(self, item):"""Add an element to the back of queue."""
newest = self._Node(item,None)# node will be new tail nodeif self.is_empty():
self._head = newest # special case : perviously emptyelse:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size +=1defconcatenate(self, q):# if not isinstance(q, (self)):# raise TypeError("q must LinkQueue")
self._tail._next = q._head
self._size += q._size
q._size =0
q._head = q._tail =Nonepassif __name__ =="__main__":
linkQueue1 = LinkQueue()
linkQueue2 = LinkQueue()[linkQueue1.enqueue(i)for i inrange(10)][linkQueue2.enqueue(i)for i inrange(10,20)]
linkQueue1.concatenate(linkQueue2)[print(linkQueue1.dequeue(),end=' ')for i inrange(len(linkQueue1))]print(linkQueue2.is_empty())
27
classEmpty(Exception):passclassLinkQueue:"""FIFO queue implementation using a singly linked list for storage."""
__slots__ ="_head","_tail","_size"class_Node:"""Lightweight,nonpublic class for storing a singly linked node."""
__slots__ ="_element","_next"# streamline memory usagedef__init__(self, element,next):# initialize node's fields
self._element = element # reference to user's element
self._next =next# reference to next nodedef__init__(self):"""Create an empty queue."""
self._head =None
self._tail =None
self._size =0# number of queue elementsdef__len__(self):"""Return the number of elements in the queue."""return self._size
defis_empty(self):"""Return True if the queue is emtpy."""return self._size ==0deffirst(self):"""Return (but do not remove) the element at the front of the queue."""if self.is_empty():raise Empty("Queue is empty")return self._head._element
defdequeue(self):"""Remove and return the first element of the queue.
Raise Emtpy exception if the queue is empty.
"""if self.is_empty():raise Empty("Queue is empty")
answer = self._head._element
self._head = self._head._next
self._size -=1if self.is_empty():# special case as queue is empty
self._tail =None# remove head had been the tailreturn answer
defenqueue(self, item):"""Add an element to the back of queue."""
newest = self._Node(item,None)# node will be new tail nodeif self.is_empty():
self._head = newest # special case : perviously emptyelse:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size +=1defconcatenate(self, q):# if not isinstance(q, (self)):# raise TypeError("q must LinkQueue")
self._tail._next = q._head
self._size += q._size
q._size =0
q._head = q._tail =Nonepassdefrecursive(self, temp,node):if node isNone:returnelse:
temp.append(node)
self.recursive(temp,node._next)defrecursive_function(self):
temp =[self._head._element]
self.recursive(temp, self._head._next)return temp
passif __name__ =="__main__":
linkQueue1 = LinkQueue()[linkQueue1.enqueue(i)for i inrange(10)]
temp = linkQueue1.recursive_function()print(temp)for i in temp:iftype(i)==int:print(i , end =' ')else:print(i._element,end =' ')
28
classEmpty(Exception):passclassLinkQueue:"""FIFO queue implementation using a singly linked list for storage."""
__slots__ ="_head","_tail","_size"class_Node:"""Lightweight,nonpublic class for storing a singly linked node."""
__slots__ ="_element","_next"# streamline memory usagedef__init__(self, element,next):# initialize node's fields
self._element = element # reference to user's element
self._next =next# reference to next nodedef__init__(self):"""Create an empty queue."""
self._head =None
self._tail =None
self._size =0# number of queue elementsdef__len__(self):"""Return the number of elements in the queue."""return self._size
defis_empty(self):"""Return True if the queue is emtpy."""return self._size ==0deffirst(self):"""Return (but do not remove) the element at the front of the queue."""if self.is_empty():raise Empty("Queue is empty")return self._head._element
defdequeue(self):"""Remove and return the first element of the queue.
Raise Emtpy exception if the queue is empty.
"""if self.is_empty():raise Empty("Queue is empty")
answer = self._head._element
self._head = self._head._next
self._size -=1if self.is_empty():# special case as queue is empty
self._tail =None# remove head had been the tailreturn answer
defenqueue(self, item):"""Add an element to the back of queue."""
newest = self._Node(item,None)# node will be new tail nodeif self.is_empty():
self._head = newest # special case : perviously emptyelse:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size +=1defconcatenate(self, q):
self._tail._next = q._head
self._size += q._size
q._size =0
q._head = q._tail =Nonepassdefrecursive(self, temp, node):if node isNone:returnelse:
temp.append(node)
self.recursive(temp, node._next)defrecursive_function(self):
temp =[self._head._element]
self.recursive(temp, self._head._next)return temp
deffunction(self, node):if node isNone:returnelse:
temp = node
node = node._next
temp._next = self._head
self._head = temp
self.function(node)defreversed(self):
walk = self._head._next
self._head._next =None
self.function(walk)passif __name__ =="__main__":
linkQueue1 = LinkQueue()[linkQueue1.enqueue(i)for i inrange(10)]
linkQueue1.reversed()[print(linkQueue1.dequeue(),end=' ')for i inrange(len(linkQueue1))]
29
classEmpty(Exception):passclassLinkList:
__slots__ ="_header","_size"class_Node:
__slots__ ="_next","_element"def__init__(self, value,next):
self._element = value
self._next =nextdef__init__(self):
self._size =0
self._header = self._Node(None,None)def__len__(self):return self._size
defis_empty(self):return self._size ==0deffirst(self):if self.is_empty():raise Empty('Link is None')return self._header._next._element
defpush(self, value):
self._header._next = self._Node(value, self._header._next)
self._size +=1defpop(self):if self.is_empty():raise Empty("Link is None")
temp = self._header._next
self._header._next = temp._next
value = temp._element
temp._next = temp._element =None
self._size -=1return value
defreversed(self):# 就地逆置
walk = self._header._next
self._header._next =Nonewhile walk isnotNone:
temp = walk
walk = walk._next
temp._next = self._header._next
self._header._next = temp
if __name__ =="__main__":
link = LinkList()[link.push(i)for i inrange(10)]
link.reversed()[print(link.pop(), end=' ')for i inrange(10)]
30
classEmpty(Exception):passclassLinkStack:
__slots__ ="_head","_size"class_Node:
__slots__ ="_element","_next"def__init__(self,element,next):
self._element = element
self._next =nextdef__init__(self):
self._head = self._Node(None,None)
self._size =0def__len__(self):return self._size
defis_empty(self):return self._size ==0deftop(self):if self.is_empty():raise Empty("Linkstack is None")return self._head._next._element
defpush(self,value):
self._head = self._Node(value,self._head)
self._size +=1defpop(self):if self.is_empty():raise Empty("LinkStack is None")
temp = self._head
self._head = self._head._next
value = temp._element
temp._element = temp._next =Nonereturn value
if __name__ =="__main__":
linkStack = LinkStack()[linkStack.push(i)for i inrange(10)][print(linkStack.pop(), end =' ')for i inrange(len(linkStack))]
31
classEmpty(Exception):passclassLinkList:
__slots__ ="_header","_size"class_Node:
__slots__ ="_next","_element"def__init__(self, value,next):
self._element = value
self._next =nextdef__init__(self):
self._size =0
self._header = self._Node(None,None)def__len__(self):return self._size
defis_empty(self):return self._size ==0deffirst(self):if self.is_empty():raise Empty('Link is None')return self._header._next._element
defpush(self, value):
self._header._next = self._Node(value, self._header._next)
self._size +=1defpop(self):if self.is_empty():raise Empty("Link is None")
temp = self._header._next
self._header._next = temp._next
value = temp._element
temp._next = temp._element =None
self._size -=1return value
defreversed(self):# 就地逆置
walk = self._header._next
# self._header._next = None# temp = self._headerwhile walk isnotNone:
temp = walk
walk = walk._next
temp._next = self._header._next
self._header._next = temp
classForwardList(LinkList):classPositional:def__init__(self, container, node):
self._container = container
self._node = node
defelement(self):return self._node._element
def__eq__(self, other):returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):returnnot(self == other)def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Positional):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header:returnNone# boundary violationelse:return self.Positional(self, node)# legitimate positiondeffirst(self):return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""
walk = self._header._next
while walk isnotNone:if walk._next isNone:break
walk = walk._next
return self._make_position(walk)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)
walk = self._header._next
while walk isnotNone:if walk._next is node._node:break
walk = walk._next
return self._make_position(walk)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)
walk = self._header._next
while walk isnotNone:if walk is node._node:break
walk = walk._next
return self._make_position(walk._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef_insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node = self._Node(e,None)
predecessor._next = node
node._next = successor
self._size +=1return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""
walk = self._header._next
while walk isnotNone:if walk._next._next isNone:break
walk = walk._next
last = self.last()._node
return self._insert_between(e, walk, last)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)
walk = self._header._next
while walk isnotNone:if walk._next is original:break
walk = walk._next
return self._insert_between(e, walk, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)
walk = self._header
while walk isnotNone:if walk._next is original:break
walk = walk._next
temp = original._element
walk._next = original._next
original._element = original._next =None
self._size -=1return temp # inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueif __name__ =="__main__":
positionList = ForwardList()[positionList.add_first(i)for i inrange(10)][print(positionList.delete(positionList.last()),end=' ')for i inrange(len(positionList))]
32
classEmpty(Exception):passclassCircularQueue:"""Queue implementation using circularly linked list for storage."""class_Node:"""Lightweight,nonpublic class for storing a singly linked node."""
__slots__ ="_element","_next"def__init__(self, element,next):
self._element = element
self._next =nextdef__init__(self):"""Create an empty queue."""
self._tail =None# will represent tail of queue
self._size =0# number of queue elementsdef__len__(self):"""Return the number of elements in the queue. """return self._size
defis_empty(self):return self._size ==0deffisrt(self):"""Return (but do not remove) the element at the front of the queue.
Raise Empty exception if the queue is empty.
"""if self.is_empty():raise Empty('the circleLinklist is iNOne')
head = self._tail._next
return head._element
defdequeue(self):"""Remove and return the first element of the queue
Raise Empty exception if the queue is empty.
"""if self.is_empty():raise Empty("Queue is empty")
oldhead = self._tail._next
if self._size ==1:# removing only element
self._tail =None# queue becomes emptyelse:
self._tail._next = oldhead._next # bypass the old head
self._size -=1return oldhead._element
defenqueue(self, e):"""Add an element to the back of queue."""
newest = self._Node(e,None)# node will be new tail nodeif self.is_empty():
newest._next = newest # initialize circularlyelse:
newest._next = self._tail._next # new node points to head
self._tail._next = newest
self._tail = newest
self._size +=1defrotate(self):"""Rotate front element to the back of the queue."""if self._size >0:
self._tail = self._tail._next # old head becomes new tailclassPositionalList(CircularQueue):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node isNone:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._tail._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._tail)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)
walk = self._tail._next
while walk._next isnot self._tail:if walk._next is node:break
walk = walk._next
return self._make_position(walk)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef_insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node = self._Node(e, successor)
predecessor._next = node
self._size +=1return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""if self._size ==0:
self._tail = self._Node(e,None)
self._tail._next = self._tail
self._size +=1else:return self._insert_between(e, self._tail, self._tail._next)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)
walk = self._tail._next
while walk isnot self._tail:if walk._next is original:break
walk = walk._next
return self._insert_between(e, walk, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)
walk = self._tail._next
while walk isnot self._tail:if walk._next is original:break
walk = walk._next
if walk._next is self._tail:
self._tail = walk
walk._next = original._next
value = original._element
original._element = original._next =None
self._size -=1return value # inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueif __name__ =='__main__':
positional = PositionalList()[positional.add_first(i)for i inrange(10)]# walk = positional._tail._next# while walk is not positional._tail:# print(walk._element)# walk = walk._next[print(positional.delete(positional.first()),end=' ')for i inrange(len(positional))]
33
class_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
defreversed(self):
walk = self._header._next
self._header._next =Nonewhile walk isnotNone:
temp = walk
walk = walk._next
temp._next = self._header
temp._prev =None
self._header._prev = temp
self._header = temp
34
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valuedefswap(self, p, q):
p = self._validate(p)
q = self._validate(q)
p._next, q._next._prev, p._prev, q._prev._next, q._next, p._next._prev, q._prev,p._prev._next = q._next, p , q._prev, p,p._next, q,p._prev,q
35
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""classiterator:def__init__(self, sequence):"""Create an iterator for the given sequence."""
self.__seq = sequence._node # keep a reference to the underlying datadef__next__(self):"""Return the next element,or else raise StopIteration error."""if self.__seq._element isnotNone:
walk = self.__seq
self.__seq = walk._next
return walk._element # return the data elementelse:raise StopIteration()# there are no more elementsdef__iter__(self):"""By convention, an iterator must return itself as an iterator"""return self
# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""return self.iterator(self.first())# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueif __name__ =="__main__":
positional = PositionalList()[positional.add_first(i)for i inrange(10)]print(len(positional))for value in positional:print(value,end=' ')
36
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header =None
self._trailer =None
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)try:
predecessor._next = newest
except Exception:
self._header = newest
try:
successor._prev = newest
except Exception:
self._trailer = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""try:
predecessor = node._prev
except Exception:
self._header = node._next
try:
successor = node._next
except Exception:
self._trailer = node._prev
try:
predecessor._next = successor
except Exception:
self._header = node._next
try:
successor._prev = predecessor
except Exception:
self._trailer = node._prev
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e,None, self._header)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer,None)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node isNone:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e,None, self._header)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer,None)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueif __name__ =="__main__":
position = PositionalList()[position.add_last(i)for i inrange(10)][print(position.delete(position.last()),end =' ')for i inrange(len(position))]
37
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header =None
self._trailer =None
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)try:
predecessor._next = newest
except Exception:
self._header = newest
try:
successor._prev = newest
except Exception:
self._trailer = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""try:
predecessor = node._prev
except Exception:
self._header = node._next
try:
successor = node._next
except Exception:
self._trailer = node._prev
try:
predecessor._next = successor
except Exception:
self._header = node._next
try:
successor._prev = predecessor
except Exception:
self._trailer = node._prev
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e,None, self._header)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer,None)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node isNone:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e,None, self._header)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer,None)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valuedeffind(self,e):
walk = self._header
while walk isnotNone:if walk._next isnotNone:if walk._next._element + walk._element == e:return self._make_position(walk), self._make_position(walk._next)
walk = walk._next
returnNoneif __name__ =="__main__":
position = PositionalList()[position.add_last(i)for i inrange(10)]print(position.find(5))[print(position.delete(position.first()),end =' ')for i inrange(len(position))]
38
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header =None
self._trailer =None
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)try:
predecessor._next = newest
except Exception:
self._header = newest
try:
successor._prev = newest
except Exception:
self._trailer = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""try:
predecessor = node._prev
except Exception:
self._header = node._next
try:
successor = node._next
except Exception:
self._trailer = node._prev
try:
predecessor._next = successor
except Exception:
self._header = node._next
try:
successor._prev = predecessor
except Exception:
self._trailer = node._prev
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e,None, self._header)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer,None)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node isNone:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e,None, self._header)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer,None)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valuedeffind(self,e):
walk = self._header
while walk isnotNone:if walk._next isnotNone:if walk._next._element + walk._element == e:return self._make_position(walk), self._make_position(walk._next)
walk = walk._next
returnNonedefbubble_sort(self):
header = self._header
while header._next isnotNone:if header._element > header._next._element:
header._element,header._next._element = header._next._element,header._element
header = header._next
if __name__ =="__main__":
position = PositionalList()[position.add_last(i)for i inrange(20,10,-1)]# print(position.find(5))# position.bubble_sort()[print(position.delete(position.first()),end =' ')for i inrange(len(position))]
39
classEmpty(Exception):passclassPositionalQueue:class_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header =None
self._trailer =None
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)try:
predecessor._next = newest
except Exception:
self._header = newest
try:
successor._prev = newest
except Exception:
self._trailer = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""try:
predecessor = node._prev
except Exception:
self._header = node._next
try:
successor = node._next
except Exception:
self._trailer = node._prev
try:
predecessor._next = successor
except Exception:
self._header = node._next
try:
successor._prev = predecessor
except Exception:
self._trailer = node._prev
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e,None, self._header)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer,None)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node isNone:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e,None, self._header)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer,None)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valuedeffind(self, e):
walk = self._header
while walk isnotNone:if walk._next isnotNone:if walk._next._element + walk._element == e:return self._make_position(walk), self._make_position(walk._next)
walk = walk._next
returnNonedefbubble_sort(self):
header = self._header
while header._next isnotNone:if header._element > header._next._element:
header._element, header._next._element = header._next._element, header._element
header = header._next
def__init__(self):
self._positional = self.PositionalList()
self._size =0def__len__(self):return self._size
defis_empty(self):return self._size ==0defpush(self, e):
self._size +=1return self._positional.add_last(e)defpop(self):if self.is_empty():raise Empty("PositionalQueue is None")
self._size -=1return self._positional.delete(self._positional.first())defdelete(self, p):
walk = self._positional._header
while walk isnotNone:if walk._element == p:
self._positional.delete(self._positional._make_position(walk))
self._size -=1return walk
walk = walk._next
returnNoneif __name__ =="__main__":
positionalQueue = PositionalQueue()[positionalQueue.push(i)for i inrange(10)]
positionalQueue.delete(1)[print(positionalQueue.pop(),end=' ')for i inrange(len(positionalQueue))]print()print(len(positionalQueue))
40
classEmpty(Exception):passclass_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header = self._Node(None,None,None)
self._trailer = self._Node(None,None,None)
self._header._next = self._trailer # trailer is after header
self._trailer._prev = self._header # header is before trailer
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)
predecessor._next = newest
successor._prev = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""
predecessor = node._prev
successor = node._next
predecessor._next = successor
successor._prev = predecessor
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._next._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._prev._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header._next)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer._prev)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._next isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node is self._header or node is self._trailer:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header._next)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer._prev)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e, self._header, self._header._next)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer._prev, self._trailer)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valueclassFavoritesList:"""List of elements ordered from most frequently accessed to least."""# ---------------nested _Item class ----------class_Item:
__slots__ ="_value","_count"# streamling memory usagedef__init__(self, e):
self._value = e # the user's element
self._count =0# access count initially zero# --------nonpublic utilities -------------------------def_find_position(self, e):"""Search for element e and return its Position(or None if not found)."""
walk = self._data.first()while walk isnotNoneand walk.element()._value != e:
walk = self._data.after(walk)return walk
def_move_up(self, p):"""Move item at Position p earlier in the list based on access count."""if p != self._data.first():
cnt = p.element()._count
walk = self._data.before(p)if cnt > walk.element()._count:# must shift forwardwhile walk != self._data.first()and cnt > self._data.before(walk).element()._count:
walk = self._data.before(walk)
self._data.add_before(walk, self._data.delete(p))# delete/reinsertdef__init__(self):"""Create an empty list of favorites."""
self._data = PositionalList()def__len__(self):"""Return number of entries on favorites list"""returnlen(self._data)defis_empty(self):"""Return True if list is empty."""returnlen(self._data)==0defaccess(self, e):"""Access element e,thereby increasing its access count."""
p = self._find_position(e)# try to locate existing elementif p isNone:
p = self._data.add_last(self._Item(e))# if new ,place at end
p.element()._count +=1# always increment count
self._move_up(p)# consider moving forwarddefremove(self, e):"""Remove element e from the list of favorites."""
p = self._find_position(e)# try to locate existing elementif p isnotNone:
self._data.delete(p)# delete,if fountdeftop(self, k):"""Generate sequence of top k elements in terms of access count."""ifnot1<= k <=len(self):raise ValueError("Illegal value for k")
walk = self._data.first()for j inrange(k):
item = walk.element()# element of list is _Itemyield item._value # report user's element
walk = self._data.after(walk)classFavoritesListMTF(FavoritesList):"""List of elements ordered with move-to-front heuristic."""# we override _move_up to provide move-to-front semanticsdef_move_up(self, p):"""Move accessed item at Position p to front of list."""if p != self._data.first():
self._data.add_first(self._data.delete(p))# delete/reinsertdeftop(self, k):"""Generate sequence of top k elements in terms of access count."""ifnot1<= k <=len(self):raise ValueError("Illegal valuue for k")# we begin by makeing a copy of the original list
temp = PositionalList()for item in self._data:# positional lists support iteration
temp.add_last(item)# we repeatedly find report,and remove element with largest countfor j inrange(k):# find and report next highest from tmep
highPos = temp.first()
walk = temp.after(highPos)while walk isnotNone:if walk.element()._count > highPos.element()._count:
highPos = walk
walk = temp.after(walk)# we have found the element with highest countyield highPos.element()._value, highPos.element()._count # report element to user
temp.delete(highPos)# remove from temp list
self.delete()defdelete(self):
walk = self._data.first()while walk isnotNone:if walk.element()._count ==1:
self._data.delete(walk)try:
walk = self._data.after(walk)except Exception:breakpassif __name__ =="__main__":
favoriteMTF = FavoritesListMTF()
favoriteMTF.access(1)
favoriteMTF.access(2)
favoriteMTF.access(2)
favoriteMTF.access(2)
favoriteMTF.access(3)
favoriteMTF.access(3)
favoriteMTF.access(3)for top, count in favoriteMTF.top(3):print(top, count)passpass
41
classEmpty(Exception):passclassLinkStack:
__slots__ ="_head","_size"class_Node:
__slots__ ="_element","_next"def__init__(self, element,next):
self._element = element
self._next =nextdef__init__(self):
self._head = self._Node(None,None)
self._size =0def__len__(self):return self._size
defis_empty(self):return self._size ==0deftop(self):if self.is_empty():raise Empty("Linkstack is None")return self._head._next._element
defpush(self, value):
self._head = self._Node(value, self._head)
self._size +=1defpop(self):if self.is_empty():raise Empty("LinkStack is None")
temp = self._head
self._head = self._head._next
value = temp._element
temp._element = temp._next =Nonereturn value
defjoin(self, linkStack):
walk = linkStack._head
k =0while k <len(linkStack)-1:
k +=1
walk = walk._next
walk._next = self._head
self._head = linkStack._head
self._size += linkStack._size
passif __name__ =="__main__":
linkStack1 = LinkStack()
linkStack2 = LinkStack()[linkStack1.push(i)for i inrange(10)][linkStack2.push(i)for i inrange(10,20)]
linkStack1.join(linkStack2)[print(linkStack1.pop(), end=' ')for i inrange(len(linkStack1))]
42
classEmpty(Exception):passclassLinkStack:
__slots__ ="_head","_size"class_Node:
__slots__ ="_element","_next"def__init__(self, element,next):
self._element = element
self._next =nextdef__init__(self):
self._head = self._Node(None,None)
self._size =0def__len__(self):return self._size
defis_empty(self):return self._size ==0deftop(self):if self.is_empty():raise Empty("Linkstack is None")return self._head._next._element
defpush(self, value):
self._head = self._Node(value, self._head)
self._size +=1defpop(self):if self.is_empty():raise Empty("LinkStack is None")
temp = self._head
self._head = self._head._next
value = temp._element
temp._element = temp._next =Nonereturn value
defjoin(self, linkStack):
walk = linkStack._head
k =0while k <len(linkStack)-1:
k +=1
walk = walk._next
walk._next = self._head
self._head = linkStack._head
self._size += linkStack._size
passclassScoreboard:"""Fixed-length sequence of high scores in nondecreseasing order."""def__init__(self):"""Initialize scoreboard with given maximum capacity.
All entries are initially None.
"""
self._board = LinkStack()# reserve space for future scores
self._n =0# number of actual entries
self.cursor = self._board._head
def__getitem__(self, item):"""Return entry at index k."""
k =0
walk = self._board._head
while k < item:
k +=1
walk = walk._next
return walk._element
def__next__(self):if self._board.is_empty()isnotNone:
walk = self.cursor
self.cursor = walk._next
return walk._element
else:raise StopIteration()def__iter__(self):return self
def__str__(self):"""Return string representation of the high score list."""return"\n".join(str(self._board[j])for j inrange(self._n))defadd(self, entry):"""Consider adding entry to high scores."""
score = entry.get_score()# Does new entry qualify as a high score?# answer is yes if board not full or score is higher than last entry
good = self._n <len(self._board)or score > self._board[-1].get_score()if good:if self._n <len(self._board):# no score drops from list
self._n +=1# so overall number increases# shift lower scores rightward to make room for new entry
j = self._n -1while j >0and self._board[j -1].get_score()< score:
self._board[j]= self._board[j -1]# shift entry from j-1 to j
j -=1# and decrement j
self._board[j]= entry # when done , add new entry
43
classEmpty(Exception):passclassLinkStack:
__slots__ ="_head","_size"class_Node:
__slots__ ="_element","_next"def__init__(self, element,next):
self._element = element
self._next =nextdef__init__(self):
self._head = self._Node(None,None)
self._size =0def__len__(self):return self._size
defis_empty(self):return self._size ==0deftop(self):if self.is_empty():raise Empty("Linkstack is None")return self._head._next._element
defpush(self, value):
self._head = self._Node(value, self._head)
self._size +=1defpop(self):if self.is_empty():raise Empty("LinkStack is None")
temp = self._head
self._head = self._head._next
value = temp._element
temp._element = temp._next =Nonereturn value
defjoin(self, linkStack):
walk = linkStack._head
k =0while k <len(linkStack)-1:
k +=1
walk = walk._next
walk._next = self._head
self._head = linkStack._head
self._size += linkStack._size
passdefsplit(self):
newLinkStack1 = LinkStack()
newLinkStack2 = LinkStack()
i =0for j inrange(len(self)):
value = self.pop()if i ==0:
newLinkStack1.push(value)
i +=1elif i ==1:
newLinkStack2.push(value)
i +=1else:
i =1
newLinkStack1.push(value)return newLinkStack1, newLinkStack2
if __name__ =="__main__":
linkStack = LinkStack()[linkStack.push(i)for i inrange(10)]
stack1, stack2 = linkStack.split()[print(stack1.pop(), end=' ')for i inrange(len(stack1))][print(stack2.pop(), end=' ')for i inrange(len(stack2))]
44
classEmpty(Exception):passclassPositionalQueue:class_DoublyLinkedBase:"""A base class providing a doubly linked list representation."""class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element","_prev","_next"# streaming memorydef__init__(self, element, prev,next):# initialize node's fields
self._element = element # use's element
self._prev = prev # previous node rederence
self._next =next# next node referencedef__init__(self):"""Create an empty list."""
self._header =None
self._trailer =None
self._size =0# number of elementsdef__len__(self):"""Return the number of elements in the list."""return self._size
defis_empty(self):"""Return True if list is empty."""return self._size ==0def_insert_between(self, e, predecessor, successor):"""Add element e between two existing nodes and return new node."""
newest = self._Node(e, predecessor, successor)try:
predecessor._next = newest
except Exception:
self._header = newest
try:
successor._prev = newest
except Exception:
self._trailer = newest
self._size +=1return newest
def_delete_node(self, node):"""Delete nonsentinel node from the list and return its element."""try:
predecessor = node._prev
except Exception:
self._header = node._next
try:
successor = node._next
except Exception:
self._trailer = node._prev
try:
predecessor._next = successor
except Exception:
self._header = node._next
try:
successor._prev = predecessor
except Exception:
self._trailer = node._prev
self._size -=1
element = node._element # record deleted element
node._prev = node._next = node._element =None# deprecate nodereturn element
classLinkedDeque(_DoublyLinkedBase):# note the use of inheritance"""Double-ended queue implementation based on a doubly linked list."""deffirst(self):"""Return (but do not remove) the element at the front of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._header._element # real item just after headerdeflast(self):"""Return (but do not remove) the element at the back of the deque."""if self.is_empty():raise Empty("Deque is empty")return self._trailer._element # readl item just before trailerdefinsert_first(self, e):"""Add an element to the front of the deuqe."""
self._insert_between(e,None, self._header)# after headerdefinsert_last(self, e):"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer,None)# before trailerdefdelete_first(self):"""Remove and return the element from the front of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._header)# use inherited methoddefdelete_last(self):"""Remove and return the element from the back of the deque.
Raise Empty exception if the deque is empty.
"""if self.is_empty():raise Empty("Deque is empty")return self._delete_node(self._trailer)# use inherited methodclassPositionalList(_DoublyLinkedBase):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node isNone:raise ValueError("p is no longer valid")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node isNone:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""return self._make_position(self._header)deflast(self):"""Return the last Position in the list (or None if list is empty)."""return self._make_position(self._trailer)defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)return self._make_position(node._prev)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)# -------------------mutators --------------------------# override inherited version to return Position,rather than Nodedef__insert_between(self, e, predecessor, successor):"""Add element between existing nodes and return new Position."""
node =super()._insert_between(e, predecessor, successor)return self._make_position(node)defadd_first(self, e):"""Insert element e at the front of the list and return new Position."""return self._insert_between(e,None, self._header)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""return self.__insert_between(e, self._trailer,None)defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original._prev, original)defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)return self._insert_between(e, original, original._next)defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)return self._delete_node(original)# inherited method returns elementdefreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valuedeffind(self, e):
walk = self._header
while walk isnotNone:if walk._next isnotNone:if walk._next._element + walk._element == e:return self._make_position(walk), self._make_position(walk._next)
walk = walk._next
returnNonedefbubble_sort(self):
header = self._header
while header._next isnotNone:if header._element > header._next._element:
header._element, header._next._element = header._next._element, header._element
header = header._next
def__init__(self):
self._positional = self.PositionalList()
self._size =0
self._cursor = self._positional.first()def__len__(self):return self._size
defis_empty(self):return self._size ==0defleft(self):if self._cursor is self._positional.first():returnNoneelse:
self._cursor = self._positional.before(self._cursor)defright(self):if self._cursor is self._positional.last():returnNoneelse:
self._cursor = self._positional.after(self._cursor)definsert(self, e):if self._cursor isNone:
self._positional._insert_between(e,None,None)
self._cursor = self._positional.first()else:
self._positional._insert_between(e, self._cursor._node,Noneif self._positional.after(self._cursor)isNoneelse self._positional.after(self._cursor)._node)
self.right()
self._size +=1defdelete(self):if self._cursor is self._positional.last():returnNoneelse:
self._size -=1
value = self._positional.delete(self._cursor)
self._cursor = self._positional.last()return value
if __name__ =="__main__":
positionalQueue = PositionalQueue()[positionalQueue.insert(i)for i inrange(10)][print(positionalQueue.delete())for i inrange(len(positionalQueue))]
45
classSparseArray:def__init__(self):
self._array =[]def__len__(self):returnlen(self._array)def__getitem__(self, item):
is_exists =False
index =Nonefor i inrange(len(self._array)):if self._array[i][0]== item:
is_exists =True
index = i
breakif is_exists:return self._array[index][1]else:raise IndexError
def__setitem__(self, key, value):
is_exists =False
index =Nonefor i inrange(len(self._array)):if self._array[i][0]== key:
is_exists =True
index = i
breakif is_exists:
self._array[index][1]= value
else:raise IndexError
defappend(self, item):
self._array.append(item)if __name__ =="__main__":
array = SparseArray()
array.append([1,5])print(array[1])
46
classEmpty(Exception):passclass_LinkStack:class_Node:"""Lightweight,nonpublic class for storing a doubly linked node."""
__slots__ ="_element",'_next'# streaming memorydef__init__(self, element,next):# initialize node's fields
self._element = element # use's element
self._next =nextdef__init__(self):
self._size =0
self._array =[]
self._head =Nonedef__len__(self):return self._size
defis_empty(self):return self._size ==0def__getitem__(self, item):if item > self._size:raise IndexError
return self._array[item]def__setitem__(self, key, value):if key > self._size:raise IndexError
self._array[key].element = value
def_append(self, value):
self._head = self._Node(value, self._head)
self._array.append(self._head)
self._size +=1def_pop(self):if self.is_empty():raise Empty
temp = self._array.pop()
self._head = temp._next
temp._element = temp._next =None
self._size -=1def_remove(self, item):if self.is_empty():raise Empty
if item >= self._size:raise IndexError
target = self._array[item]
walk = self._head
if target == walk:
self._head = walk._next
else:while walk isnotNone:if walk._next == target:break
walk = walk._next
walk._next = target._next
self._array = self._array[:item]+ self._array[item +1:]
self._size -=1classPositionalList(_LinkStack):"""A sequential container of elements allowing positional accress."""# ----------- nested Position class ------------classPosition:"""An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# opposite of __eq__# --------------- utility method --------------------------------def_validate(self, p):"""Return position's node ,or raise appropriate error if invalid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")return p._node
# ---------------------utility method -------------def_make_position(self, node):"""Return Position instance for given node (or None if sentinel)"""if node isNone:returnNone# boundary violationelse:return self.Position(self, node)# legitimate positiondeffirst(self):"""Return the first Position in the list (or None if list is empty)."""if self.is_empty():returnNoneelse:return self._make_position(self[0])deflast(self):"""Return the last Position in the list (or None if list is empty)."""if self.is_empty():returnNoneelse:return self._make_position(self[self._size-1])defbefore(self, p):"""Return the Position just before Position p (or None if p is first)."""
node = self._validate(p)
walk = self._head
if walk == node:returnNoneelse:while walk isnotNone:if walk._next == node:break
walk = walk._next
return self._make_position(walk)defafter(self, p):"""Return the Position just after Position p (or None if p is last)."""
node = self._validate(p)return self._make_position(node._next)def__iter__(self):"""Generate a forward iteration of the elements of the list."""
cursor = self.first()while cursor isnotNone:yield cursor.element()
cursor = self.after(cursor)else:returnNonedefadd_first(self, e):"""Insert element e at the front of the list and return new Position."""if self.is_empty():
self._append(e)return self._make_position(self[0])else:
self._head = self._Node(e, self._head)
self._array =[self._head]+ self._array
self._size +=1return self._make_position(self._head)defadd_last(self, e):"""Insert element e at the back of the list and return new Postion."""if self.is_empty():
self._append(e)return self._make_position(self[0])else:
node = self._Node(e,None)
last_node = self.last()._node
last_node._next = node
self._array = self._array +[node]
self._size +=1defadd_before(self, p, e):"""Insert element e into list before Position p and return new Position."""
original = self._validate(p)
successor = self.before(self._make_position(original))if successor isNone:
node = self._Node(e, self._head)
self._head = node
self._array =[node]+ self._array
else:
node = self._Node(e, original)
successor._node._next = node
index =0for i inrange(len(self)):if self[i]== successor:breakelse:
index +=1
self._array = self._array[:index-1]+[node]+ self._array[index-1:]
self._size +=1defadd_after(self, p, e):"""Insert element e into list after Position p and return new Position."""
original = self._validate(p)
successor = self.after(self._make_position(original))
node = self._Node(e, successor._node if successor isnotNoneelseNone)
original._next = node
index =0for i inrange(len(self)):if self[i]== original:break
index +=1
self._array = self._array[:index +1]+[node]+ self._array[index +1:]
self._size +=1defdelete(self, p):"""Remove and return the element at Position p."""
original = self._validate(p)
successor = self.after(p)# 后继
predecessor = self.before(p)# 前驱if predecessor isNone:
self._head =Noneif successor isNoneelse successor._node
self._array = self._array[1:]elif successor isNone:
self._array = self._array[:-1]
predecessor._node._next =Noneelse:
predecessor._node._next = successor._node
index =0for i inrange(len(self)):if self[i]== successor._node:break
index +=1
self._array = self._array[:index-1]+ self._array[index:]
original._element = original._next =None
self._size -=1defreplace(self, p, e):"""Replace the element at Position p with e.
Return the element formerly at Position p.
"""
original = self._validate(p)
old_value = original._element # temporarily store old element
original._element = e # replace with new elementreturn old_value # return the old element valuedefget(self):return self._make_position(self._head._next)if __name__ =="__main__":
positional = PositionalList()
positional.add_last(3)
positional.add_last(5)
positional.add_before(positional.last(),4)
positional.add_last(7)
positional.add_before(positional.first(),2)
positional.add_before(positional.last(),6)
positional.add_before(positional.first(),1)
positional.delete(positional.get())
positional.delete(positional.get())
positional.delete(positional.last())# positional.delete(positional.last())# positional.delete(positional.last())
positional.delete(positional.first())# positional.delete(positional.first())# positional.delete(positional.first())for position in positional:print(position, end=' ')
47
import random
classEmpty(Exception):passclassLinklist:class_Node:
__slots__ ='_element','_next'def__init__(self, element,next):
self._element = element
self._next =nextdef__init__(self):
self._size =0
self._head =Nonedef__len__(self):return self._size
defis_empty(self):return self._size ==0deffirst(self):if self.is_empty():raise Empty()return self._head
defenqueue(self, successor, e):if successor isNone:
self._head = self._Node(e, self._head)else:
node = self._Node(e, successor._next)
successor._next = node
self._size +=1defdequeue(self):if self.is_empty():raise Empty()
temp = self._head
self._head = self._head._next
value = temp._element
temp._element = temp._next =None
self._size -=1return value
classCardHand:def__init__(self):
self._spades = Linklist()# 黑桃
self._square = Linklist()# 方块
self._peach = Linklist()# 红桃
self._plum = Linklist()# 梅花
self._style =[self._spades,self._square,self._peach,self._plum]
self._card =['A']
self._card.extend([str(i)for i inrange(2,11)])
self._card.extend(['J',"Q","K"])def_is_exists(self, linklist, e):"""
判断花色牌是否存在
:param e:
:return:
"""
walk = linklist._head
exists =Falsewhile walk isnotNone:if walk._element == e:
exists =Truebreak
walk = walk._next
return exists
def_random_achieve(self):return random.choice(self._card)def_add(self, cards, r, s):"""
往指定花色牌中添加牌
:param cards: 目标卡片
:param r: 目标位置
:param s: 花色
:return:
"""
k =0
walk = cards._head
while walk isnotNone:if k == r:break
walk = walk._next
else:iflen(cards)>= r:passelse:raise IndexError
card = self._random_achieve()whileTrue:ifnot self._is_exists(cards, s + card):
cards.enqueue(walk, s + card)break
card = self._random_achieve()defadd_card(self, r, s):"""
在花色s牌上位置为r处添加一张牌
:param r:
:param s:
:return:
"""if s is'spades':
self._add(self._spades, r, s)elif s is'square':
self._add(self._square, r, s)elif s is'peach':
self._add(self._peach, r, s)elif s is'plum':
self._add(self._peach, r, s)else:raise ValueError
def_isplays(self, card):if card.is_empty():
style_copy = self._style.copy()whilelen(style_copy)!=0:
chooice = random.choice(style_copy)if chooice == card:
style_copy.remove(chooice)else:return chooice.dequeue()else:return self._spades.dequeue()defplays(self, s):"""
从花色s的牌中移除或者取出一张牌。如果s中没有牌,则从手中移除或去除一张牌
:param s:
:return:
"""if s is'spades':return self._isplays(self._spades)elif s is'square':return self._isplays(self._square)elif s is'peach':return self._isplays(self._peach)elif s is'plum':return self._isplays(self._plum)else:raise ValueError
def__iter__(self):for card in self.all_of_suit('spades'):yield card
for card in self.all_of_suit('square'):yield card
for card in self.all_of_suit('peach'):yield card
for card in self.all_of_suit('plum'):yield card
def_iter_part(self, card):
walk = card._head
while walk isnotNone:yield walk._element
walk = walk._next
defall_of_suit(self, s):if s is'spades':for card in self._iter_part(self._spades):yield card
elif s is'square':for card in self._iter_part(self._square):yield card
elif s is'peach':for card in self._iter_part(self._peach):yield card
elif s is'plum':for card in self._iter_part(self._plum):yield card
else:raise ValueError
if __name__ =="__main__":
cards = CardHand()
cards.add_card(0,'spades')
cards.add_card(1,'spades')
cards.add_card(0,'square')
cards.add_card(1,'square')
cards.add_card(0,'peach')
cards.add_card(1,'peach')
cards.add_card(0,'plum')
cards.add_card(1,'plum')print(cards.plays('spades'))print(cards.plays('spades'))print(cards.plays('spades'))for card in cards:print(card, end=' ')
7.22class Empty(Exception): passclass _DoublyLinkedBase: """A base class providing a doubly linked list representation.""" class _Node: """Lightweight,nonpublic class for storing a doubly linked node.""" __slots__ = "_eleme