很抱歉代码没有及时更新,我决定以后会把自己的代码都分享出来
1
class Empty(Exception):
pass
class Linkstack:
__slots__ = "_size", "_head"
class _Node:
__slots__ = "_element", "_next"
def __init__(self, element, next):
self._element = element
self._next = next
def __init__(self):
self._size = 0
self._head = None
def __len__(self):
return self._size
def is_empty(self):
return len(self) == 0
def push(self, item):
self._head = self._Node(item, self._head)
self._size += 1
def pop(self):
if self.is_empty():
raise Empty("the node is None")
answer = self._head._element
self._head = self._head._next
self._size -= 1
return answer
def top(self):
if self.is_empty():
raise Empty("the node is None")
return self._head
def find(self):
walk = self._head._next
while walk._next is not None:
yield walk._element
walk = walk._next
if __name__ == "__main__":
link = Linkstack()
[link.push(i) for i in range(10)]
for i in link.find():
print(i)
2
class Empty(Exception):
pass
class LinkStack:
__slots__ = "_head", "_size"
class _Node:
__slots__ = "_element", "_next"
def __init__(self, element, next):
self._element = element
self._next = next
def __init__(self):
self._head = None
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return self._size == 0
def top(self):
if self.is_empty():
raise Empty("the linkstack is None")
return self._head._element
def push(self, item):
self._head = self._Node(item, self._head)
self._size += 1
def pop(self):
if self.is_empty():
raise Empty("the linkstack is None")
answer = self._head._element
self._head = self._head._next
self._size -= 1
return answer
def tail(self):
walk = self._head
while walk is not None:
walk = walk._next
if walk._next is None:
return walk
def concat(self, item):
temp = item.tail()
temp._next = self._head
self._head = item._head
self._size += item._size
if __name__ == "__main__":
L = LinkStack()
M = LinkStack()
[L.push(i) for i in range(10)]
[M.push(i) for i in range(10, 20)]
L.concat(M)
print([L.pop() for i in range(20)])
3
class Empty(Exception):
pass
class LinkStack:
__slots__ = "_head", "_size"
class _Node:
__slots__ = "_element", "_next"
def __init__(self, element, next):
self._element = element
self._next = next
def __init__(self):
self._head = None
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return self._size == 0
def top(self):
if self.is_empty():
raise Empty("the linkstack is None")
return self._head._element
def push(self, item):
self._head = self._Node(item, self._head)
self._size += 1
def pop(self):
if self.is_empty():
raise Empty("the linkstack is None")
answer = self._head._element
self._head = self._head._next
self._size -= 1
return answer
def tail(self):
walk = self._head
while walk is not None:
walk = walk._next
if walk._next is None:
return walk
def concat(self, item):
temp = item.tail()
temp._next = self._head
self._head = item._head
self._size += item._size
def sum(stack):
if stack.is_empty():
return 0
else:
stack.pop()
return 1 + sum(stack)
if __name__ == "__main__":
L = LinkStack()
M = LinkStack()
[L.push(i) for i in range(10)]
[M.push(i) for i in range(10, 20)]
L.concat(M)
print(len(L))
print(sum(L))
# print([L.pop() for i in range(20)])
4
import random
class Empty(Exception):
pass
class LinkStack:
__slots__ = "_head", "_size"
class _Node:
__slots__ = "_element", "_next"
def __init__(self, element, next):
self._element = element
self._next = next
def __init__(self):
self._head = None
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return self._size == 0
def top(self):
if self.is_empty():
raise Empty("the linkstack is None")
return self._head._element
def push(self, item):
self._head = self._Node(item, self._head)
self._size += 1
def pop(self):
if self.is_empty():
raise Empty("the linkstack is None")
answer = self._head._element
self._head = self._head._next
self._size -= 1
return answer
def tail(self):
walk = self._head
while walk is not None:
walk = walk._next
if walk._next is None:
return walk
def concat(self, item):
temp = item.tail()
temp._next = self._head
self._head = item._head
self._size += item._size
def get_random_node(self):
walk = self._head
temp = []
while walk._next is not None:
temp.append(walk)
walk = walk._next
return random.choices(temp, k=2)
def exchange(self):
node1, node2 = self.get_random_node()
walk = self._head
while walk._next is not None:
if walk._next == node1:
new_walk = self._head
while new_walk._next is not None:
if new_walk._next == node2:
break
new_walk = new_walk._next
walk._next, node2._next, new_walk._next, node1._next = node2, node1._next, node1, node2._next # 利用同时分配技术
break
walk = walk._next
pass
def sum(stack):
if stack.is_empty():
return 0
else:
stack.pop()
return 1 + sum(stack)
if __name__ == "__main__":
L = LinkStack()
M = LinkStack()
[L.push(i) for i in range(10)]
[M.push(i) for i in range(10, 20)]
L.concat(M)
print(len(L))
print(L.exchange())
print([L.pop() for i in range(20)])
5
class Empty(Exception):
pass
class CircleStack:
__slots__ = "_tail", "_size"
class _Node:
__slots__ = "_element", "_next"
def __init__(self, element, next):
self._element = element
self._next = next
def __init__(self):
self._tail = None
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return self._size == 0
def first(self):
if self.is_empty():
raise Empty("CircleStack is None")
return self._tail._next
def dequeue(self):
if self.is_empty():
raise Empty("CircleStack is None")
answer = self._tail._next
if self._size == 1:
self._tail = None
else:
self._tail._next = answer._next
self._size -= 1
return answer._element
def enqueue(self, e):
node = self._Node(e, None)
if self._size == 0:
node._next = node
else:
node._next = self._tail._next
self._tail._next = node
self._tail = node
self._size += 1
def rotate(self, k=5):
if self.is_empty():
raise Empty("CircleStack is None")
walk = self._tail
i = 0
while i < k and walk is not None:
walk = walk._next
i += 1
self._tail = walk
if __name__ == "__main__":
circleStack = CircleStack()
[circleStack.enqueue(i) for i in range(10)]
circleStack.rotatate(2)
print(len(circleStack))
[print(circleStack.dequeue(), end=' ') for i in range(10)]
6
import random
class Empty(Exception):
pass
class CircleStack:
__slots__ = "_tail", "_size"
class _Node:
__slots__ = "_element", "_next", "_container"
def __init__(self, element, next):
self._element = element
self._next = next
self._container = None
def __init__(self):
self._tail = None
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return self._size == 0
def first(self):
if self.is_empty():
raise Empty("CircleStack is None")
return self._tail._next
def dequeue(self):
if self.is_empty():
raise Empty("CircleStack is None")
answer = self._tail._next
if self._size == 1:
self._tail = None
else:
self._tail._next = answer._next
self._size -= 1
return answer._element
def enqueue(self, e):
node = self._Node(e, None)
if self._size == 0:
node._next = node
else:
node._next = self._tail._next
self._tail._next = node
self._tail = node
self._size += 1
def rotate(self, k=5):
if self.is_empty():
raise Empty("CircleStack is None")
walk = self._tail
i = 0
while i < k and walk is not None:
walk = walk._next
i += 1
self._tail = walk
def get_random_node(self):
walk = self._tail._next
temp = []
while walk._next != self._tail:
temp.append(walk)
walk = walk._next
node = random.choices(temp, k=1)[-1]
node._container = self
return node
def validate(self, node):
if not isinstance(node, self._Node):
return False
if node._container is not self:
return False
return True
if __name__ == "__main__":
circleStack1 = CircleStack()
circleStack2 = CircleStack()
[circleStack1.enqueue(i) for i in range(10)]
[circleStack2.enqueue(i) for i in range(10)]
node1 = circleStack1.get_random_node()
node2 = circleStack2.get_random_node()
print(circleStack1.validate(node1))
[print(circleStack1.dequeue(), end=' ') for i in range(10)]
7
class Empty(Exception):
pass
class LinkQueue:
"""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 usage
def __init__(self, element, next): # initialize node's fields
self._element = element # reference to user's element
self._next = next # reference to next node
def __init__(self):
"""Create an empty queue."""
self._head = None
self._tail = None
self._size = 0 # number of queue elements
def __len__(self):
"""Return the number of elements in the queue."""
return self._size
def is_empty(self):
"""Return True if the queue is emtpy."""
return self._size == 0
def first(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
def dequeue(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 -= 1
if self.is_empty(): # special case as queue is empty
self._tail = None # remove head had been the tail
return answer
def enqueue(self, item):
"""Add an element to the back of queue."""
newest = self._Node(item, None) # node will be new tail node
if self.is_empty():
self._head = newest # special case : perviously empty
else:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size += 1
def rotate(self, k=5):
walk = self._head
temp = None
i = 0
while i < k:
walk = walk._next
if i == k - 1:
temp = walk
i += 1
self._tail._next = self._head
self._tail = temp
self._head = walk
if __name__ == "__main__":
linkQueue = LinkQueue()
[linkQueue.enqueue(i) for i in range(10)]
linkQueue.rotate()
[print(linkQueue.dequeue()) for i in range(10)]
8
class Empty(Exception):
pass
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 memory
def __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 reference
def __init__(self):
"""Create an empty list."""
self._header = self._Node(None, None, None)
self._tailer = self._Node(None, None, None)
self._header._next = self._tailer # trailer is after header
self._tailer._prev = self._header # header is before trailer
self._size = 0 # number of elements
def __len__(self):
"""Return the number of elements in the list."""
return self._size
def is_empty(self):
"""Return True if list is empty."""
return self._size == 0
def _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 += 1
return 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 node
return element
def enqueue(self, item):
if self._size == 0:
self._insert_between(item, self._header, self._tailer)
else:
self._insert_between(item, self._tailer._prev, self._tailer)
self._size += 1
def dequeue(self):
if self.is_empty():
raise Empty("the doublelinked is None!")
return self._delete_node(self._header._next)
def midNode(self):
walk1 = self._header._next
walk2 = self._tailer._prev
node = None
while walk1._next is not None and walk2._prev is not None:
node = walk1
walk1 = walk1._next
walk2 = walk2._prev
if walk1 == walk2:
return node._element
if walk1._next == walk2:
return walk1._next._element
if __name__ == "__main__":
doubleLink = DoublyLinkedBase()
[doubleLink.enqueue(i) for i in range(10)]
print(doubleLink.midNode())
[print(doubleLink.dequeue()) for i in range(10)]
9
class Empty(Exception):
pass
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 memory
def __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 reference
def __init__(self):
"""Create an empty list."""
self._header = self._Node(None, None, None)
self._tailer = self._Node(None, None, None)
self._header._next = self._tailer # trailer is after header
self._tailer._prev = self._header # header is before trailer
self._size = 0 # number of elements
def __len__(self):
"""Return the number of elements in the list."""
return self._size
def is_empty(self):
"""Return True if list is empty."""
return self._size == 0
def _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 += 1
return 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 node
return element
def enqueue(self, item):
if self._size == 0:
self._insert_between(item, self._header, self._tailer)
else:
self._insert_between(item, self._tailer._prev, self._tailer)
self._size += 1
def dequeue(self):
if self.is_empty():
raise Empty("the doublelinked is None!")
return self._delete_node(self._header._next)
def midNode(self):
walk1 = self._header._next
walk2 = self._tailer._prev
node = None
while walk1._next is not None and walk2._prev is not None:
node = walk1
walk1 = walk1._next
walk2 = walk2._prev
if walk1 == walk2:
return node._element
if walk1._next == walk2:
return walk1._next._element
def concat(self, doubleLink):
self._tailer._prev._next = doubleLink._header._next
doubleLink._tailer._prev._next = self._tailer
pass
if __name__ == "__main__":
L = DoublyLinkedBase()
M = DoublyLinkedBase()
[L.enqueue(i) for i in range(10)]
[M.enqueue(i) for i in range(10,20)]
L.concat(M)
[print(L.dequeue()) for i in range(20)]
11
class Empty(Exception):
pass
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 memory
def __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 reference
def __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 elements
def __len__(self):
"""Return the number of elements in the list."""
return self._size
def is_empty(self):
"""Return True if list is empty."""
return self._size == 0
def _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 += 1
return 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 node
return element
class LinkedDeque(_DoublyLinkedBase): # note the use of inheritance
"""Double-ended queue implementation based on a doubly linked list."""
def first(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 header
def last(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 trailer
def insert_first(self, e):
"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next) # after header
def insert_last(self, e):
"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer) # before trailer
def delete_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 method
def delete_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 method
class PositionalList(_DoublyLinkedBase):
"""A sequential container of elements allowing positional accress."""
# ----------- nested Position class ------------
class Position:
"""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
def element(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."""
return type(other) is type(self) and other._node is self._node
def __ne__(self, other):
"""Return True if other does not represent the same location."""
return not (self == other) # opposite of __eq__
# --------------- utility method --------------------------------
def _validate(self, p):
"""Return position's node ,or raise appropriate error if invalid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._next is None:
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:
return None # boundary violation
else:
return self.Position(self, node) # legitimate position
def first(self):
"""Return the first Position in the list (or None if list is empty)."""
return self._make_position(self._header._next)
def last(self):
"""Return the last Position in the list (or None if list is empty)."""
return self._make_position(self._trailer._prev)
def before(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)
def after(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 is not None:
yield cursor.element()
cursor = self.after(cursor)
# -------------------mutators --------------------------
# override inherited version to return Position,rather than Node
def __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)
def add_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)
def add_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)
def add_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)
def add_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)
def delete(self, p):
"""Remove and return the element at Position p."""
original = self._validate(p)
return self._delete_node(original) # inherited method returns element
def replace(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 element
return old_value # return the old element value
def max(self):
temp = []
walk = self._header._next
while walk._next is not None:
temp.append(walk._element)
walk = walk._next
return max(temp)
if __name__ == "__main__":
positionalList = PositionalList()
[positionalList.add_first(i) for i in range(10)]
print(positionalList.max())
12
class Empty(Exception):
pass
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 memory
def __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 reference
def __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 elements
def __len__(self):
"""Return the number of elements in the list."""
return self._size
def is_empty(self):
"""Return True if list is empty."""
return self._size == 0
def _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 += 1
return 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 node
return element
class LinkedDeque(_DoublyLinkedBase): # note the use of inheritance
"""Double-ended queue implementation based on a doubly linked list."""
def first(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 header
def last(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 trailer
def insert_first(self, e):
"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next) # after header
def insert_last(self, e):
"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer) # before trailer
def delete_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 method
def delete_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 method
class PositionalList(_DoublyLinkedBase):
"""A sequential container of elements allowing positional accress."""
# ----------- nested Position class ------------
class Position:
"""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
def element(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."""
return type(other) is type(self) and other._node is self._node
def __ne__(self, other):
"""Return True if other does not represent the same location."""
return not (self == other) # opposite of __eq__
# --------------- utility method --------------------------------
def _validate(self, p):
"""Return position's node ,or raise appropriate error if invalid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._next is None:
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:
return None # boundary violation
else:
return self.Position(self, node) # legitimate position
def first(self):
"""Return the first Position in the list (or None if list is empty)."""
return self._make_position(self._header._next)
def last(self):
"""Return the last Position in the list (or None if list is empty)."""
return self._make_position(self._trailer._prev)
def before(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)
def after(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 is not None:
yield cursor.element()
cursor = self.after(cursor)
# -------------------mutators --------------------------
# override inherited version to return Position,rather than Node
def __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)
def add_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)
def add_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)
def add_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)
def add_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)
def delete(self, p):
"""Remove and return the element at Position p."""
original = self._validate(p)
return self._delete_node(original) # inherited method returns element
def replace(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 element
return old_value # return the old element value
# def max(self):
# temp = []
# walk = self._header._next
# while walk._next is not None:
# temp.append(walk._element)
# walk = walk._next
# return max(temp)
def max(self):
walk = self.first()
value = self.first().element()
while self.before(walk) is not None:
if value < self.before(walk).element():
value = self.before(walk).element()
walk = self.before(walk)
return value
if __name__ == "__main__":
positionalList = PositionalList()
[positionalList.add_first(i) for i in range(10)]
print(positionalList.max())
13
class Empty(Exception):
pass
class doubleLinkeBase:
class _Node:
__slots__ = "_element", "_prev", "_next"
def __init__(self, element, prev, next):
self._element = element
self._prev = prev
self._next = next
def __init__(self):
self._header = self._Node(None, None, None)
self._tailer = self._Node(None, None, None)
self._header._next = self._tailer
self._tailer._prev = self._header
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return len(self) == 0
def _insert_between(self, e, predecessor, successor):
node = self._Node(e, predecessor, successor)
predecessor._next = node
successor._prev = node
self._size += 1
return node
def _delete_node(self, node):
predecessor = node._prev
successor = node._next
element = node._element
predecessor._next = successor
successor._prev = predecessor
self._size -= 1
node._element = node._prev = node._next = None
return element
class LinkDeque(doubleLinkeBase):
def first(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._header._next._element
def last(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._tailer._prev._element
def insert_first(self, e):
self._insert_between(e, self._header, self._header._next)
def insert_last(self, e):
self._insert_between(e, self._tailer._prev, self._tailer)
def delete_first(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._delete_node(self._header._next)
def delete_last(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._delete_node(self._tailer._prev)
class PositionalList(doubleLinkeBase):
class Position:
__slots__ = "_container", "_node"
def __init__(self, container, node):
self._container = container
self._node = node
def element(self):
return self._node._element
def __eq__(self, other):
return type(other) is type(self) and other._node is self._node
def __ne__(self, other):
return not (self == other)
def _validate(self, p):
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._next is None:
raise ValueError("p is no longer valid")
return p._node
def _make_position(self, node):
if node is self._header or node is self._tailer:
return None
else:
return self.Position(self, node)
def first(self):
return self._make_position(self._header._next)
def last(self):
return self._make_position(self._tailer._prev)
def before(self, p):
node = self._validate(p)
return self._make_position(node._prev)
def after(self, p):
node = self._validate(p)
return self._make_position(node._next)
def __iter__(self):
cursor = self.first()
while cursor is not None:
yield cursor.element()
cursor = self.after(cursor)
def __insert_between(self, e, predecessor, successor):
node = super()._insert_between(e, predecessor, successor)
return self._make_position(node)
def add_first(self, p):
return self.__insert_between(p, self._header, self._header._next)
def add_last(self, p):
return self.__insert_between(p, self._tailer._prev, self._tailer)
def add_before(self, p, e):
node = self._validate(p)
return self.__insert_between(e, node._prev, node)
def add_after(self, p, e):
node = self._validate(p)
return self.__insert_between(e, node, node._next)
def delete(self, p):
node = self._validate(p)
return self._delete_node(node)
def replace(self, p, e):
node = self._validate(p)
old_value = node._element
node._element = e
return old_value
def find(self, e):
count = 0
walk = self.first()
while self.after(walk) is not None:
if walk.element() == e:
return count
count += 1
walk = self.after(walk)
else:
return None
if __name__ == "__main__":
positionalList = PositionalList()
[positionalList.add_first(i) for i in range(10)]
positionalList.replace(positionalList.first(), 5)
print(positionalList.first().element())
print(positionalList.find(5))
14
class Empty(Exception):
pass
class doubleLinkeBase:
class _Node:
__slots__ = "_element", "_prev", "_next"
def __init__(self, element, prev, next):
self._element = element
self._prev = prev
self._next = next
def __init__(self):
self._header = self._Node(None, None, None)
self._tailer = self._Node(None, None, None)
self._header._next = self._tailer
self._tailer._prev = self._header
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return len(self) == 0
def _insert_between(self, e, predecessor, successor):
node = self._Node(e, predecessor, successor)
predecessor._next = node
successor._prev = node
self._size += 1
return node
def _delete_node(self, node):
predecessor = node._prev
successor = node._next
element = node._element
predecessor._next = successor
successor._prev = predecessor
self._size -= 1
node._element = node._prev = node._next = None
return element
class LinkDeque(doubleLinkeBase):
def first(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._header._next._element
def last(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._tailer._prev._element
def insert_first(self, e):
self._insert_between(e, self._header, self._header._next)
def insert_last(self, e):
self._insert_between(e, self._tailer._prev, self._tailer)
def delete_first(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._delete_node(self._header._next)
def delete_last(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._delete_node(self._tailer._prev)
class PositionalList(doubleLinkeBase):
class Position:
__slots__ = "_container", "_node"
def __init__(self, container, node):
self._container = container
self._node = node
def element(self):
return self._node._element
def __eq__(self, other):
return type(other) is type(self) and other._node is self._node
def __ne__(self, other):
return not (self == other)
def __int__(self):
self._cursor = self._header._next
def _validate(self, p):
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._next is None:
raise ValueError("p is no longer valid")
return p._node
def _make_position(self, node):
if node is self._header or node is self._tailer:
return None
else:
return self.Position(self, node)
def first(self):
return self._make_position(self._header._next)
def last(self):
return self._make_position(self._tailer._prev)
def before(self, p):
node = self._validate(p)
return self._make_position(node._prev)
def after(self, p):
node = self._validate(p)
return self._make_position(node._next)
def __iter__(self):
cursor = self.first()
while cursor is not None:
yield cursor.element()
cursor = self.after(cursor)
def __insert_between(self, e, predecessor, successor):
node = super()._insert_between(e, predecessor, successor)
return self._make_position(node)
def add_first(self, p):
return self.__insert_between(p, self._header, self._header._next)
def add_last(self, p):
return self.__insert_between(p, self._tailer._prev, self._tailer)
def add_before(self, p, e):
node = self._validate(p)
return self.__insert_between(e, node._prev, node)
def add_after(self, p, e):
node = self._validate(p)
return self.__insert_between(e, node, node._next)
def delete(self, p):
node = self._validate(p)
return self._delete_node(node)
def replace(self, p, e):
node = self._validate(p)
old_value = node._element
node._element = e
return old_value
def find_count(self, cursor, element):
if cursor is None:
return 0
else:
if cursor.element() == element:
return 1
else:
cursor = self.after(cursor)
total = self.find_count(cursor, element)
return 1 + total
def find(self, e):
walk = self.first()
count = self.find_count(walk, e)
if count == 0:
return None
else:
return count-1
if __name__ == "__main__":
positionalList = PositionalList()
[positionalList.add_first(i) for i in range(10)]
print(positionalList.first().element())
print(positionalList.find(0))
15
class Empty(Exception):
pass
class doubleLinkeBase:
class _Node:
__slots__ = "_element", "_prev", "_next"
def __init__(self, element, prev, next):
self._element = element
self._prev = prev
self._next = next
def __init__(self):
self._header = self._Node(None, None, None)
self._tailer = self._Node(None, None, None)
self._header._next = self._tailer
self._tailer._prev = self._header
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return len(self) == 0
def _insert_between(self, e, predecessor, successor):
node = self._Node(e, predecessor, successor)
predecessor._next = node
successor._prev = node
self._size += 1
return node
def _delete_node(self, node):
predecessor = node._prev
successor = node._next
element = node._element
predecessor._next = successor
successor._prev = predecessor
self._size -= 1
node._element = node._prev = node._next = None
return element
class LinkDeque(doubleLinkeBase):
def first(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._header._next._element
def last(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._tailer._prev._element
def insert_first(self, e):
self._insert_between(e, self._header, self._header._next)
def insert_last(self, e):
self._insert_between(e, self._tailer._prev, self._tailer)
def delete_first(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._delete_node(self._header._next)
def delete_last(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._delete_node(self._tailer._prev)
class PositionalList(doubleLinkeBase):
class Position:
__slots__ = "_container", "_node"
def __init__(self, container, node):
self._container = container
self._node = node
def element(self):
return self._node._element
def __eq__(self, other):
return type(other) is type(self) and other._node is self._node
def __ne__(self, other):
return not (self == other)
def __int__(self):
self._cursor = self._header._next
def _validate(self, p):
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._next is None:
raise ValueError("p is no longer valid")
return p._node
def _make_position(self, node):
if node is self._header or node is self._tailer:
return None
else:
return self.Position(self, node)
def first(self):
return self._make_position(self._header._next)
def last(self):
return self._make_position(self._tailer._prev)
def before(self, p):
node = self._validate(p)
return self._make_position(node._prev)
def after(self, p):
node = self._validate(p)
return self._make_position(node._next)
def __iter__(self):
cursor = self.first()
while cursor is not None:
yield cursor.element()
cursor = self.after(cursor)
def __insert_between(self, e, predecessor, successor):
node = super()._insert_between(e, predecessor, successor)
return self._make_position(node)
def add_first(self, p):
return self.__insert_between(p, self._header, self._header._next)
def add_last(self, p):
return self.__insert_between(p, self._tailer._prev, self._tailer)
def add_before(self, p, e):
node = self._validate(p)
return self.__insert_between(e, node._prev, node)
def add_after(self, p, e):
node = self._validate(p)
return self.__insert_between(e, node, node._next)
def delete(self, p):
node = self._validate(p)
return self._delete_node(node)
def replace(self, p, e):
node = self._validate(p)
old_value = node._element
node._element = e
return old_value
def find_count(self, cursor, element):
if cursor is None:
return 0
else:
if cursor.element() == element:
return 1
else:
cursor = self.after(cursor)
total = self.find_count(cursor, element)
return 1 + total
def find(self, e):
walk = self.first()
count = self.find_count(walk, e)
if count == 0:
return None
else:
return count - 1
def __reversed__(self):
cursor = self.last()
while cursor is not None:
yield cursor.element()
cursor = self.before(cursor)
if __name__ == "__main__":
positionalList = PositionalList()
[positionalList.add_first(i) for i in range(10)]
for element in positionalList.__reversed__():
print(element)
16
class Empty(Exception):
pass
class doubleLinkeBase:
class _Node:
__slots__ = "_element", "_prev", "_next"
def __init__(self, element, prev, next):
self._element = element
self._prev = prev
self._next = next
def __init__(self):
self._header = self._Node(None, None, None)
self._tailer = self._Node(None, None, None)
self._header._next = self._tailer
self._tailer._prev = self._header
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return len(self) == 0
def _insert_between(self, e, predecessor, successor):
node = self._Node(e, predecessor, successor)
predecessor._next = node
successor._prev = node
self._size += 1
return node
def _delete_node(self, node):
predecessor = node._prev
successor = node._next
element = node._element
predecessor._next = successor
successor._prev = predecessor
self._size -= 1
node._element = node._prev = node._next = None
return element
class LinkDeque(doubleLinkeBase):
def first(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._header._next._element
def last(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._tailer._prev._element
def insert_first(self, e):
self._insert_between(e, self._header, self._header._next)
def insert_last(self, e):
self._insert_between(e, self._tailer._prev, self._tailer)
def delete_first(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._delete_node(self._header._next)
def delete_last(self):
if self.is_empty():
raise Empty("the LinkDeque is None")
return self._delete_node(self._tailer._prev)
class PositionalList(doubleLinkeBase):
class Position:
__slots__ = "_container", "_node"
def __init__(self, container, node):
self._container = container
self._node = node
def element(self):
return self._node._element
def __eq__(self, other):
return type(other) is type(self) and other._node is self._node
def __ne__(self, other):
return not (self == other)
def __int__(self):
self._cursor = self._header._next
def _validate(self, p):
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._next is None:
raise ValueError("p is no longer valid")
return p._node
def _make_position(self, node):
if node is self._header or node is self._tailer:
return None
else:
return self.Position(self, node)
def first(self):
return self._make_position(self._header._next)
def last(self):
return self._make_position(self._tailer._prev)
def before(self, p):
node = self._validate(p)
return self._make_position(node._prev)
def after(self, p):
node = self._validate(p)
return self._make_position(node._next)
def __iter__(self):
cursor = self.first()
while cursor is not None:
yield cursor.element()
cursor = self.after(cursor)
def __insert_between(self, e, predecessor, successor):
node = super()._insert_between(e, predecessor, successor)
return self._make_position(node)
def add_first(self, p):
return self.__insert_between(p, self._header, self._header._next)
def add_last(self, p):
return self.add_after(self.last(),p)
def add_before(self, p, e):
return self.add_after(p,e)
def add_after(self, p, e):
node = self._validate(p)
return self.__insert_between(e, node, node._next)
def delete(self, p):
node = self._validate(p)
return self._delete_node(node)
def replace(self, p, e):
node = self._validate(p)
old_value = node._element
node._element = e
return old_value
def find_count(self, cursor, element):
if cursor is None:
return 0
else:
if cursor.element() == element:
return 1
else:
cursor = self.after(cursor)
total = self.find_count(cursor, element)
return 1 + total
def find(self, e):
walk = self.first()
count = self.find_count(walk, e)
if count == 0:
return None
else:
return count - 1
def __reversed__(self):
cursor = self.last()
while cursor is not None:
yield cursor.element()
cursor = self.before(cursor)
if __name__ == "__main__":
positionalList = PositionalList()
[positionalList.add_first(i) for i in range(10)]
positionalList.add_last(100)
positionalList.add_before(positionalList.first(),99)
[print(positionalList.delete(positionalList.last())) for i in range(11)]
17
class Empty(Exception):
pass
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 memory
def __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 reference
def __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 elements
def __len__(self):
"""Return the number of elements in the list."""
return self._size
def is_empty(self):
"""Return True if list is empty."""
return self._size == 0
def _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 += 1
return 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 node
return element
class LinkedDeque(_DoublyLinkedBase): # note the use of inheritance
"""Double-ended queue implementation based on a doubly linked list."""
def first(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 header
def last(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 trailer
def insert_first(self, e):
"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next) # after header
def insert_last(self, e):
"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer) # before trailer
def delete_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 method
def delete_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 method
class PositionalList(_DoublyLinkedBase):
"""A sequential container of elements allowing positional accress."""
# ----------- nested Position class ------------
class Position:
"""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
def element(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."""
return type(other) is type(self) and other._node is self._node
def __ne__(self, other):
"""Return True if other does not represent the same location."""
return not (self == other) # opposite of __eq__
# --------------- utility method --------------------------------
def _validate(self, p):
"""Return position's node ,or raise appropriate error if invalid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._next is None:
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:
return None # boundary violation
else:
return self.Position(self, node) # legitimate position
def first(self):
"""Return the first Position in the list (or None if list is empty)."""
return self._make_position(self._header._next)
def last(self):
"""Return the last Position in the list (or None if list is empty)."""
return self._make_position(self._trailer._prev)
def before(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)
def after(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 is not None:
yield cursor.element()
cursor = self.after(cursor)
# -------------------mutators --------------------------
# override inherited version to return Position,rather than Node
def __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)
def add_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)
def add_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)
def add_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)
def add_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)
def delete(self, p):
"""Remove and return the element at Position p."""
original = self._validate(p)
return self._delete_node(original) # inherited method returns element
def replace(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 element
return old_value # return the old element value
def move_to_front(self, p):
walk = self.first()
while walk is not None:
if walk.element() == p:
break
walk = self.after(walk)
else:
raise ValueError("index is not valid")
element = self.delete(walk)
self.add_first(element)
if __name__ == "__main__":
positialList = PositionalList()
[positialList.add_last(i) for i in range(10,20)]
positialList.move_to_front(12)
[print(positialList.delete(positialList.first()),end=' ') for i in range(9)]
pass
18
class Empty(Exception):
pass
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 memory
def __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 reference
def __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 elements
def __len__(self):
"""Return the number of elements in the list."""
return self._size
def is_empty(self):
"""Return True if list is empty."""
return self._size == 0
def _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 += 1
return 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 node
return element
class LinkedDeque(_DoublyLinkedBase): # note the use of inheritance
"""Double-ended queue implementation based on a doubly linked list."""
def first(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 header
def last(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 trailer
def insert_first(self, e):
"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next) # after header
def insert_last(self, e):
"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer) # before trailer
def delete_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 method
def delete_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 method
class PositionalList(_DoublyLinkedBase):
"""A sequential container of elements allowing positional accress."""
# ----------- nested Position class ------------
class Position:
"""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
def element(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."""
return type(other) is type(self) and other._node is self._node
def __ne__(self, other):
"""Return True if other does not represent the same location."""
return not (self == other) # opposite of __eq__
# --------------- utility method --------------------------------
def _validate(self, p):
"""Return position's node ,or raise appropriate error if invalid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._next is None:
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:
return None # boundary violation
else:
return self.Position(self, node) # legitimate position
def first(self):
"""Return the first Position in the list (or None if list is empty)."""
return self._make_position(self._header._next)
def last(self):
"""Return the last Position in the list (or None if list is empty)."""
return self._make_position(self._trailer._prev)
def before(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)
def after(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 is not None:
yield cursor.element()
cursor = self.after(cursor)
# -------------------mutators --------------------------
# override inherited version to return Position,rather than Node
def __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)
def add_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)
def add_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)
def add_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)
def add_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)
def delete(self, p):
"""Remove and return the element at Position p."""
original = self._validate(p)
return self._delete_node(original) # inherited method returns element
def replace(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 element
return old_value # return the old element value
class FavoritesList:
"""List of elements ordered from most frequently accessed to least."""
# ---------------nested _Item class ----------
class _Item:
__slots__ = "_value", "_count" # streamling memory usage
def __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 is not None and 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 forward
while 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/reinsert
def __init__(self):
"""Create an empty list of favorites."""
self._data = PositionalList()
def __len__(self):
"""Return number of entries on favorites list"""
return len(self._data)
def is_empty(self):
"""Return True if list is empty."""
return len(self._data) == 0
def access(self, e):
"""Access element e,thereby increasing its access count."""
p = self._find_position(e) # try to locate existing element
if p is None:
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 forward
def remove(self, e):
"""Remove element e from the list of favorites."""
p = self._find_position(e) # try to locate existing element
if p is not None:
self._data.delete(p) # delete,if fount
def top(self, k):
"""Generate sequence of top k elements in terms of access count."""
if not 1 <= k <= len(self):
raise ValueError("Illegal value for k")
walk = self._data.first()
for j in range(k):
item = walk.element() # element of list is _Item
yield item._value # report user's element
walk = self._data.after(walk)
if __name__ == "__main__":
favoritelist = FavoritesList()
favoritelist.access('a')
favoritelist.access('b')
favoritelist.access('c')
favoritelist.access('d')
favoritelist.access('e')
favoritelist.access('f')
favoritelist.access('a')
favoritelist.access('c')
favoritelist.access('f')
favoritelist.access('b')
favoritelist.access('d')
favoritelist.access('e')
for result in favoritelist.top(5):
print(result,end=' ')
20
class Empty(Exception):
pass
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 memory
def __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 reference
def __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 elements
def __len__(self):
"""Return the number of elements in the list."""
return self._size
def is_empty(self):
"""Return True if list is empty."""
return self._size == 0
def _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 += 1
return 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 node
return element
class LinkedDeque(_DoublyLinkedBase): # note the use of inheritance
"""Double-ended queue implementation based on a doubly linked list."""
def first(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 header
def last(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 trailer
def insert_first(self, e):
"""Add an element to the front of the deuqe."""
self._insert_between(e, self._header, self._header._next) # after header
def insert_last(self, e):
"""Add an element to the back of the deque."""
self._insert_between(e, self._trailer._prev, self._trailer) # before trailer
def delete_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 method
def delete_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 method
class PositionalList(_DoublyLinkedBase):
"""A sequential container of elements allowing positional accress."""
# ----------- nested Position class ------------
class Position:
"""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
def element(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."""
return type(other) is type(self) and other._node is self._node
def __ne__(self, other):
"""Return True if other does not represent the same location."""
return not (self == other) # opposite of __eq__
# --------------- utility method --------------------------------
def _validate(self, p):
"""Return position's node ,or raise appropriate error if invalid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._next is None:
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:
return None # boundary violation
else:
return self.Position(self, node) # legitimate position
def first(self):
"""Return the first Position in the list (or None if list is empty)."""
return self._make_position(self._header._next)
def last(self):
"""Return the last Position in the list (or None if list is empty)."""
return self._make_position(self._trailer._prev)
def before(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)
def after(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 is not None:
yield cursor.element()
cursor = self.after(cursor)
# -------------------mutators --------------------------
# override inherited version to return Position,rather than Node
def __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)
def add_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)
def add_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)
def add_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)
def add_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)
def delete(self, p):
"""Remove and return the element at Position p."""
original = self._validate(p)
return self._delete_node(original) # inherited method returns element
def replace(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 element
return old_value # return the old element value
class FavoritesList:
"""List of elements ordered from most frequently accessed to least."""
# ---------------nested _Item class ----------
class _Item:
__slots__ = "_value", "_count" # streamling memory usage
def __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 is not None and 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 forward
while 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/reinsert
def __init__(self):
"""Create an empty list of favorites."""
self._data = PositionalList()
def __len__(self):
"""Return number of entries on favorites list"""
return len(self._data)
def is_empty(self):
"""Return True if list is empty."""
return len(self._data) == 0
def access(self, e):
"""Access element e,thereby increasing its access count."""
p = self._find_position(e) # try to locate existing element
if p is None:
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 forward
def remove(self, e):
"""Remove element e from the list of favorites."""
p = self._find_position(e) # try to locate existing element
if p is not None:
self._data.delete(p) # delete,if fount
def top(self, k):
"""Generate sequence of top k elements in terms of access count."""
if not 1 <= k <= len(self):
raise ValueError("Illegal value for k")
walk = self._data.first()
for j in range(k):
item = walk.element() # element of list is _Item
yield item._value # report user's element
walk = self._data.after(walk)
def reversed(self):
walk = self._data.first()
temp = PositionalList()
while walk is not None:
temp.add_first(walk.element())
walk = self._data.after(walk)
self._data = temp
if __name__ == "__main__":
favoritelist = FavoritesList()
favoritelist.access('a')
favoritelist.access('b')
favoritelist.access('c')
favoritelist.reversed()
for value in favoritelist.top(3):
print(value,end=' ')