python数据结构第七章课后习题答案(二)

22

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

    def clear(self):
        if len(self._data) == 0:
            raise Empty("the favoritesList is empty")
        walk = self._data
        while len(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

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,item._count  # 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

    def clear(self):
        if len(self._data) == 0:
            raise Empty("the favoritesList is empty")
        walk = self._data
        while len(walk) != 0:
            walk.delete(walk.first())

    def reset_counts(self):
        walk = self._data.first()
        while walk is not None:
            walk.element()._count = 0
            walk = self._data.after(walk)
        pass


if __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

class Empty(Exception):
    pass


class Stack:
    __slots__ = "_header", "_size"

    class _Node:
        __slots__ = "_next", "_element"

        def __init__(self, value, next):
            self._element = value
            self._next = next

    def __init__(self):
        self._size = 0
        self._header = self._Node(None, None)

    def __len__(self):
        return self._size

    def is_empty(self):
        return self._size == 0

    def top(self):
        if self.is_empty():
            raise Empty('stack is None')
        return self._header._next._element

    def push(self, value):
        self._header._next = self._Node(value, self._header._next)
        self._size += 1

    def pop(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 -= 1
        return value


if __name__ == "__main__":
    stack = Stack()
    [stack.push(i) for i in range(10)]
    [print(stack.pop(), end=' ') for i in range(10)]

25

class Empty(Exception):
    pass


class Queue:
    __slots__ = "_header", "_size"

    class _Node:
        __slots__ = "_element", "_next"

        def __init__(self, element, next):
            self._element = element
            self._next = next

    def __init__(self):
        self._header = self._Node(None, 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("queue is None")
        return self._header._next._element

    def dequeue(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 -= 1
        return value

    def enqueue(self, value):
        node = self._Node(value, None)
        walk = self._header
        while True:
            if walk._next is None:
                break
            walk = walk._next
        walk._next = node
        self._size += 1


if __name__ == "__main__":
    queque = Queue()
    [queque.enqueue(i) for i in range(10)]
    [print(queque.dequeue(), end=' ') for i in range(10)]

26

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 concatenate(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 = None
        pass


if __name__ == "__main__":
    linkQueue1 = LinkQueue()
    linkQueue2 = LinkQueue()
    [linkQueue1.enqueue(i) for i in range(10)]
    [linkQueue2.enqueue(i) for i in range(10,20)]
    linkQueue1.concatenate(linkQueue2)
    [print(linkQueue1.dequeue(),end=' ') for i in range(len(linkQueue1))]
    print(linkQueue2.is_empty())

27

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 concatenate(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 = None
        pass

    def recursive(self, temp,node):
        if node is None:
            return 
        else:
            temp.append(node)
            self.recursive(temp,node._next)

    def recursive_function(self):
        temp = [self._head._element]
        self.recursive(temp, self._head._next)
        return temp
        pass


if __name__ == "__main__":
    linkQueue1 = LinkQueue()
    [linkQueue1.enqueue(i) for i in range(10)]
    temp  = linkQueue1.recursive_function()
    print(temp)
    for i in temp:
        if type(i) == int:
            print(i , end = ' ')
        else:
            print(i._element,end = ' ')

28

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 concatenate(self, q):
        self._tail._next = q._head
        self._size += q._size
        q._size = 0
        q._head = q._tail = None
        pass

    def recursive(self, temp, node):
        if node is None:
            return
        else:
            temp.append(node)
            self.recursive(temp, node._next)

    def recursive_function(self):
        temp = [self._head._element]
        self.recursive(temp, self._head._next)
        return temp

    def function(self, node):
        if node is None:
            return 
        else:
            temp = node
            node = node._next
            temp._next = self._head
            self._head = temp
            self.function(node)

    def reversed(self):
        walk = self._head._next
        self._head._next = None
        self.function(walk)
        pass


if __name__ == "__main__":
    linkQueue1 = LinkQueue()
    [linkQueue1.enqueue(i) for i in range(10)]
    linkQueue1.reversed()
    [print(linkQueue1.dequeue() ,end=' ') for i in range(len(linkQueue1))]

29

class Empty(Exception):
    pass


class LinkList:
    __slots__ = "_header", "_size"

    class _Node:
        __slots__ = "_next", "_element"

        def __init__(self, value, next):
            self._element = value
            self._next = next

    def __init__(self):
        self._size = 0
        self._header = self._Node(None, None)

    def __len__(self):
        return self._size

    def is_empty(self):
        return self._size == 0

    def first(self):
        if self.is_empty():
            raise Empty('Link is None')
        return self._header._next._element

    def push(self, value):
        self._header._next = self._Node(value, self._header._next)
        self._size += 1

    def pop(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 -= 1
        return value

    def reversed(self):  # 就地逆置
        walk = self._header._next
        self._header._next = None
        while walk is not None:
            temp = walk
            walk = walk._next
            temp._next = self._header._next
            self._header._next = temp


if __name__ == "__main__":
    link = LinkList()
    [link.push(i) for i in range(10)]
    link.reversed()
    [print(link.pop(), end=' ') for i in range(10)]

30

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 = self._Node(None,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("Linkstack is None")
        return self._head._next._element

    def push(self,value):
        self._head = self._Node(value,self._head)
        self._size +=1

    def pop(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 = None
        return value


if __name__ == "__main__":
    linkStack = LinkStack()
    [linkStack.push(i) for i in range(10)]
    [print(linkStack.pop() , end = ' ') for i in range(len(linkStack))]

31

class Empty(Exception):
    pass


class LinkList:
    __slots__ = "_header", "_size"

    class _Node:
        __slots__ = "_next", "_element"

        def __init__(self, value, next):
            self._element = value
            self._next = next

    def __init__(self):
        self._size = 0
        self._header = self._Node(None, None)

    def __len__(self):
        return self._size

    def is_empty(self):
        return self._size == 0

    def first(self):
        if self.is_empty():
            raise Empty('Link is None')
        return self._header._next._element

    def push(self, value):
        self._header._next = self._Node(value, self._header._next)
        self._size += 1

    def pop(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 -= 1
        return value

    def reversed(self):  # 就地逆置
        walk = self._header._next
        # self._header._next = None
        # temp = self._header
        while walk is not None:
            temp = walk
            walk = walk._next
            temp._next = self._header._next
            self._header._next = temp


class ForwardList(LinkList):
    class Positional:
        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):
        """Return position's node ,or raise appropriate error if invalid."""
        if not isinstance(p, self.Positional):
            raise TypeError("p must be proper Position type")
        if p._container is not 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:
            return None  # boundary violation
        else:
            return self.Positional(self, node)  # legitimate position

    def first(self):
        return self._make_position(self._header._next)

    def last(self):
        """Return the last Position in the list (or None if list is empty)."""
        walk = self._header._next
        while walk is not None:
            if walk._next is None:
                break
            walk = walk._next
        return self._make_position(walk)

    def before(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 is not None:
            if walk._next is node._node:
                break
            walk = walk._next
        return self._make_position(walk)

    def after(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 is not None:
            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 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 = self._Node(e, None)
        predecessor._next = node
        node._next = successor
        self._size +=1
        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."""
        walk = self._header._next
        while walk is not None:
            if walk._next._next is None:
                break
            walk = walk._next
        last = self.last()._node
        return self._insert_between(e, walk, last)

    def add_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 is not None:
            if walk._next is original:
                break
            walk = walk._next
        return self._insert_between(e, walk, 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)
        walk = self._header
        while walk is not None:
            if walk._next is original:
                break
            walk = walk._next
        temp = original._element
        walk._next = original._next
        original._element = original._next = None
        self._size -=1
        return temp  # 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


if __name__ == "__main__":
    positionList = ForwardList()
    [positionList.add_first(i) for i in range(10)]
    [print(positionList.delete(positionList.last()),end=' ') for i in range(len(positionList))]

32

class Empty(Exception):
    pass


class CircularQueue:
    """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 = next

    def __init__(self):
        """Create an empty queue."""
        self._tail = None  # will represent tail of queue
        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 self._size == 0

    def fisrt(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

    def dequeue(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 empty
        else:
            self._tail._next = oldhead._next  # bypass the old head
        self._size -= 1
        return oldhead._element

    def enqueue(self, e):
        """Add an element to the back of queue."""
        newest = self._Node(e, None)  # node will be new tail node
        if self.is_empty():
            newest._next = newest  # initialize circularly
        else:
            newest._next = self._tail._next  # new node points to head
            self._tail._next = newest
        self._tail = newest
        self._size += 1

    def rotate(self):
        """Rotate front element to the back of the queue."""
        if self._size > 0:
            self._tail = self._tail._next  # old head becomes new tail


class PositionalList(CircularQueue):
    """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")
        return p._node

        # ---------------------utility method -------------

    def _make_position(self, node):
        """Return Position instance for given node (or None if sentinel)"""
        if node is None:
            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._tail._next)

    def last(self):
        """Return the last Position in the list (or None if list is empty)."""
        return self._make_position(self._tail)

    def before(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 is not self._tail:
            if walk._next is node:
                break
            walk = walk._next
        return self._make_position(walk)

    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 = self._Node(e, successor)
        predecessor._next = node
        self._size += 1
        return self._make_position(node)

    def add_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 += 1
        else:
            return self._insert_between(e, self._tail, self._tail._next)

    def add_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 is not self._tail:
            if walk._next is original:
                break
            walk = walk._next
        return self._insert_between(e, walk, 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)
        walk = self._tail._next
        while walk is not 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 -= 1
        return value  # 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


if __name__ == '__main__':
    positional = PositionalList()
    [positional.add_first(i) for i in range(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 in range(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 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

    def reversed(self):
        walk = self._header._next
        self._header._next = None
        while walk is not None:
            temp = walk
            walk = walk._next
            temp._next = self._header
            temp._prev = None
            self._header._prev = temp
            self._header = temp

34

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 swap(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

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."""

    class iterator:
        def __init__(self, sequence):
            """Create an iterator for the given sequence."""
            self.__seq = sequence._node  # keep a reference to the underlying data

        def __next__(self):
            """Return the next element,or else raise StopIteration error."""
            if self.__seq._element is not None:
                walk = self.__seq
                self.__seq = walk._next
                return walk._element  # return the data element
            else:
                raise StopIteration()  # there are no more elements

        def __iter__(self):
            """By convention, an iterator must return itself as an iterator"""
            return self

    # -----------  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."""
        return self.iterator(self.first())

    # -------------------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


if __name__ == "__main__":
    positional = PositionalList()
    [positional.add_first(i) for i in range(10)]
    print(len(positional))
    for value in positional:
        print(value,end=' ')

36

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 = None
        self._trailer = None
        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)
        try:
            predecessor._next = newest
        except Exception:
            self._header = newest
        try:
            successor._prev = newest
        except  Exception:
            self._trailer = newest
        self._size += 1
        return 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 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._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._element  # readl item just before trailer

    def insert_first(self, e):
        """Add an element to the front of the deuqe."""
        self._insert_between(e, None, self._header)  # after header

    def insert_last(self, e):
        """Add an element to the back of the deque."""
        self._insert_between(e, self._trailer, None)  # 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)  # 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)  # 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 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 None:
            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)

    def last(self):
        """Return the last Position in the list (or None if list is empty)."""
        return self._make_position(self._trailer)

    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, None, self._header)

    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, None)

    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


if __name__ == "__main__":
    position = PositionalList()
    [position.add_last(i) for i in range(10)]
    [print(position.delete(position.last()),end = ' ') for i in range(len(position))]

37

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 = None
        self._trailer = None
        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)
        try:
            predecessor._next = newest
        except Exception:
            self._header = newest
        try:
            successor._prev = newest
        except  Exception:
            self._trailer = newest
        self._size += 1
        return 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 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._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._element  # readl item just before trailer

    def insert_first(self, e):
        """Add an element to the front of the deuqe."""
        self._insert_between(e, None, self._header)  # after header

    def insert_last(self, e):
        """Add an element to the back of the deque."""
        self._insert_between(e, self._trailer, None)  # 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)  # 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)  # 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 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 None:
            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)

    def last(self):
        """Return the last Position in the list (or None if list is empty)."""
        return self._make_position(self._trailer)

    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, None, self._header)

    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, None)

    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 find(self,e):
        walk = self._header
        while walk is not None:
            if walk._next is not None:
                if walk._next._element + walk._element == e:
                    return self._make_position(walk) , self._make_position(walk._next)
            walk = walk._next
        return None

if __name__ == "__main__":
    position = PositionalList()
    [position.add_last(i) for i in range(10)]
    print(position.find(5))
    [print(position.delete(position.first()),end = ' ') for i in range(len(position))]

38

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 = None
        self._trailer = None
        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)
        try:
            predecessor._next = newest
        except Exception:
            self._header = newest
        try:
            successor._prev = newest
        except  Exception:
            self._trailer = newest
        self._size += 1
        return 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 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._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._element  # readl item just before trailer

    def insert_first(self, e):
        """Add an element to the front of the deuqe."""
        self._insert_between(e, None, self._header)  # after header

    def insert_last(self, e):
        """Add an element to the back of the deque."""
        self._insert_between(e, self._trailer, None)  # 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)  # 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)  # 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 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 None:
            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)

    def last(self):
        """Return the last Position in the list (or None if list is empty)."""
        return self._make_position(self._trailer)

    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, None, self._header)

    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, None)

    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 find(self,e):
        walk = self._header
        while walk is not None:
            if walk._next is not None:
                if walk._next._element + walk._element == e:
                    return self._make_position(walk) , self._make_position(walk._next)
            walk = walk._next
        return None

    def bubble_sort(self):
        header = self._header
        while header._next is not None:
            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 in range(20,10,-1)]
    # print(position.find(5))
    # position.bubble_sort()
    [print(position.delete(position.first()),end = ' ') for i in range(len(position))]

39

class Empty(Exception):
    pass


class PositionalQueue:
    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 = None
            self._trailer = None
            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)
            try:
                predecessor._next = newest
            except Exception:
                self._header = newest
            try:
                successor._prev = newest
            except  Exception:
                self._trailer = newest
            self._size += 1
            return 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 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._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._element  # readl item just before trailer

        def insert_first(self, e):
            """Add an element to the front of the deuqe."""
            self._insert_between(e, None, self._header)  # after header

        def insert_last(self, e):
            """Add an element to the back of the deque."""
            self._insert_between(e, self._trailer, None)  # 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)  # 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)  # 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 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 None:
                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)

        def last(self):
            """Return the last Position in the list (or None if list is empty)."""
            return self._make_position(self._trailer)

        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, None, self._header)

        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, None)

        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 find(self, e):
            walk = self._header
            while walk is not None:
                if walk._next is not None:
                    if walk._next._element + walk._element == e:
                        return self._make_position(walk), self._make_position(walk._next)
                walk = walk._next
            return None

        def bubble_sort(self):
            header = self._header
            while header._next is not None:
                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

    def __len__(self):
        return self._size

    def is_empty(self):
        return self._size == 0

    def push(self, e):
        self._size += 1
        return self._positional.add_last(e)

    def pop(self):
        if self.is_empty():
            raise Empty("PositionalQueue is None")
        self._size -= 1
        return self._positional.delete(self._positional.first())

    def delete(self, p):
        walk = self._positional._header
        while walk is not None:
            if walk._element == p:
                self._positional.delete(self._positional._make_position(walk))
                self._size -=1
                return walk
            walk = walk._next
        return None


if __name__ == "__main__":
    positionalQueue = PositionalQueue()
    [positionalQueue.push(i) for i in range(10)]
    positionalQueue.delete(1)
    [print(positionalQueue.pop(),end=' ') for i in range(len(positionalQueue))]
    print()
    print(len(positionalQueue))

40

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)


class FavoritesListMTF(FavoritesList):
    """List of elements ordered with move-to-front heuristic."""

    # we override _move_up to provide move-to-front semantics
    def _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/reinsert

    def top(self, k):
        """Generate sequence of top k elements in terms of access count."""
        if not 1 <= 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 count
        for j in range(k):
            # find and report next highest from tmep
            highPos = temp.first()
            walk = temp.after(highPos)
            while walk is not None:
                if walk.element()._count > highPos.element()._count:
                    highPos = walk
                walk = temp.after(walk)
            # we have found the element with highest count
            yield highPos.element()._value, highPos.element()._count  # report element to user
            temp.delete(highPos)  # remove from temp list
        self.delete()

    def delete(self):
        walk = self._data.first()
        while walk is not None:
            if walk.element()._count == 1:
                self._data.delete(walk)
            try:
                walk = self._data.after(walk)
            except Exception:
                break

        pass


if __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)
        pass
    pass

41

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 = self._Node(None, 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("Linkstack is None")
        return self._head._next._element

    def push(self, value):
        self._head = self._Node(value, self._head)
        self._size += 1

    def pop(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 = None
        return value

    def join(self, linkStack):
        walk = linkStack._head
        k = 0
        while k < len(linkStack) - 1:
            k += 1
            walk = walk._next
        walk._next = self._head
        self._head = linkStack._head
        self._size += linkStack._size
        pass


if __name__ == "__main__":
    linkStack1 = LinkStack()
    linkStack2 = LinkStack()
    [linkStack1.push(i) for i in range(10)]
    [linkStack2.push(i) for i in range(10, 20)]
    linkStack1.join(linkStack2)
    [print(linkStack1.pop(), end=' ') for i in range(len(linkStack1))]


42

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 = self._Node(None, 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("Linkstack is None")
        return self._head._next._element

    def push(self, value):
        self._head = self._Node(value, self._head)
        self._size += 1

    def pop(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 = None
        return value

    def join(self, linkStack):
        walk = linkStack._head
        k = 0
        while k < len(linkStack) - 1:
            k += 1
            walk = walk._next
        walk._next = self._head
        self._head = linkStack._head
        self._size += linkStack._size
        pass


class Scoreboard:
    """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() is not None:
            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 in range(self._n))

    def add(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 - 1
            while j > 0 and 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

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 = self._Node(None, 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("Linkstack is None")
        return self._head._next._element

    def push(self, value):
        self._head = self._Node(value, self._head)
        self._size += 1

    def pop(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 = None
        return value

    def join(self, linkStack):
        walk = linkStack._head
        k = 0
        while k < len(linkStack) - 1:
            k += 1
            walk = walk._next
        walk._next = self._head
        self._head = linkStack._head
        self._size += linkStack._size
        pass

    def split(self):
        newLinkStack1 = LinkStack()
        newLinkStack2 = LinkStack()
        i = 0
        for j in range(len(self)):
            value = self.pop()
            if i == 0:
                newLinkStack1.push(value)
                i += 1
            elif i == 1:
                newLinkStack2.push(value)
                i += 1
            else:
                i = 1
                newLinkStack1.push(value)
        return newLinkStack1, newLinkStack2


if __name__ == "__main__":
    linkStack = LinkStack()
    [linkStack.push(i) for i in range(10)]
    stack1, stack2 = linkStack.split()
    [print(stack1.pop(), end=' ') for i in range(len(stack1))]
    [print(stack2.pop(), end=' ') for i in range(len(stack2))]

44

class Empty(Exception):
    pass


class PositionalQueue:
    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 = None
            self._trailer = None
            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)
            try:
                predecessor._next = newest
            except Exception:
                self._header = newest
            try:
                successor._prev = newest
            except  Exception:
                self._trailer = newest
            self._size += 1
            return 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 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._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._element  # readl item just before trailer

        def insert_first(self, e):
            """Add an element to the front of the deuqe."""
            self._insert_between(e, None, self._header)  # after header

        def insert_last(self, e):
            """Add an element to the back of the deque."""
            self._insert_between(e, self._trailer, None)  # 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)  # 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)  # 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 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 None:
                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)

        def last(self):
            """Return the last Position in the list (or None if list is empty)."""
            return self._make_position(self._trailer)

        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, None, self._header)

        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, None)

        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 find(self, e):
            walk = self._header
            while walk is not None:
                if walk._next is not None:
                    if walk._next._element + walk._element == e:
                        return self._make_position(walk), self._make_position(walk._next)
                walk = walk._next
            return None

        def bubble_sort(self):
            header = self._header
            while header._next is not None:
                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

    def is_empty(self):
        return self._size == 0

    def left(self):
        if self._cursor is self._positional.first():
            return None
        else:
            self._cursor = self._positional.before(self._cursor)

    def right(self):
        if self._cursor is self._positional.last():
            return None
        else:
            self._cursor = self._positional.after(self._cursor)

    def insert(self, e):
        if self._cursor is None:
            self._positional._insert_between(e, None, None)
            self._cursor = self._positional.first()
        else:
            self._positional._insert_between(e, self._cursor._node, None if self._positional.after(self._cursor) is None else self._positional.after(self._cursor)._node)
            self.right()
        self._size += 1

    def delete(self):
        if self._cursor is self._positional.last():
            return None
        else:
            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 in range(10)]
    [print(positionalQueue.delete()) for i in range(len(positionalQueue))]

45

class SparseArray:
    def __init__(self):
        self._array = []

    def __len__(self):
        return len(self._array)

    def __getitem__(self, item):
        is_exists = False
        index = None
        for i in range(len(self._array)):
            if self._array[i][0] == item:
                is_exists = True
                index = i
                break
        if is_exists:
            return self._array[index][1]
        else:
            raise IndexError

    def __setitem__(self, key, value):
        is_exists = False
        index = None
        for i in range(len(self._array)):
            if self._array[i][0] == key:
                is_exists = True
                index = i
                break
        if is_exists:
            self._array[index][1] = value
        else:
            raise IndexError

    def append(self, item):
        self._array.append(item)

if __name__ == "__main__":
    array = SparseArray()
    array.append([1,5])
    print(array[1])

46

class Empty(Exception):
    pass


class _LinkStack:
    class _Node:
        """Lightweight,nonpublic class for storing a doubly linked node."""
        __slots__ = "_element", '_next'  # streaming memory

        def __init__(self, element, next):  # initialize node's fields
            self._element = element  # use's element
            self._next = next

    def __init__(self):
        self._size = 0
        self._array = []
        self._head = None

    def __len__(self):
        return self._size

    def is_empty(self):
        return self._size == 0

    def __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 += 1

    def _pop(self):
        if self.is_empty():
            raise Empty
        temp = self._array.pop()
        self._head = temp._next
        temp._element = temp._next = None
        self._size -= 1

    def _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 is not None:
                if walk._next == target:
                    break
                walk = walk._next
        walk._next = target._next
        self._array = self._array[:item] + self._array[item + 1:]
        self._size -= 1


class PositionalList(_LinkStack):
    """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")
        return p._node

        # ---------------------utility method -------------

    def _make_position(self, node):
        """Return Position instance for given node (or None if sentinel)"""
        if node is None:
            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)."""
        if self.is_empty():
            return None
        else:
            return self._make_position(self[0])

    def last(self):
        """Return the last Position in the list (or None if list is empty)."""
        if self.is_empty():
            return None
        else:
            return self._make_position(self[self._size-1])


    def before(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:
            return None
        else:
            while walk is not None:
                if walk._next == node:
                    break
                walk = walk._next
        return self._make_position(walk)

    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)
        else:
            return None

    def add_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 += 1
            return self._make_position(self._head)

    def add_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 += 1

    def add_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 is None:
            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 = 0
            for i in range(len(self)):
                if self[i] == successor:
                    break
                else:
                    index += 1
            self._array = self._array[:index-1] + [node] + self._array[index-1:]
        self._size += 1

    def add_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 is not None else None)
        original._next = node
        index = 0
        for i in range(len(self)):
            if self[i] == original:
                break
            index += 1
        self._array = self._array[:index + 1] + [node] + self._array[index + 1:]
        self._size += 1

    def delete(self, p):
        """Remove and return the element at Position p."""
        original = self._validate(p)
        successor = self.after(p)  # 后继
        predecessor = self.before(p)  # 前驱
        if predecessor is None:
            self._head = None if successor is None else successor._node
            self._array = self._array[1:]
        elif successor is None:
            self._array = self._array[:-1]
            predecessor._node._next = None
        else:
            predecessor._node._next = successor._node
            index = 0
            for i in range(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 -= 1

    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 get(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


class Empty(Exception):
    pass


class Linklist:
    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 self._size == 0

    def first(self):
        if self.is_empty():
            raise Empty()
        return self._head

    def enqueue(self, successor, e):
        if successor is None:
            self._head = self._Node(e, self._head)
        else:
            node = self._Node(e, successor._next)
            successor._next = node
        self._size += 1

    def dequeue(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 -=1
        return value


class CardHand:
    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 in range(2, 11)])
        self._card.extend(['J', "Q", "K"])

    def _is_exists(self, linklist, e):
        """
        判断花色牌是否存在
        :param e:
        :return:
        """
        walk = linklist._head
        exists = False
        while walk is not None:
            if walk._element == e:
                exists = True
                break
            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 is not None:
            if k == r:
                break
            walk = walk._next
        else:
            if len(cards) >= r:
                pass
            else:
                raise IndexError
        card = self._random_achieve()
        while True:
            if not self._is_exists(cards, s + card):
                cards.enqueue(walk, s + card)
                break
            card = self._random_achieve()

    def add_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()
            while len(style_copy)!=0:
                chooice = random.choice(style_copy)
                if chooice == card:
                    style_copy.remove(chooice)
                else:
                    return chooice.dequeue()
        else:
            return self._spades.dequeue()


    def plays(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 is not None:
            yield walk._element
            walk = walk._next

    def all_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=' ')

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北漂的阿狸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值