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

很抱歉代码没有及时更新,我决定以后会把自己的代码都分享出来

这里写目录标题

1

class Empty(Exception):
    pass


class Linkstack:
    __slots__ = "_size", "_head"

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

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

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

    def __len__(self):
        return self._size

    def is_empty(self):
        return len(self) == 0

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

    def pop(self):
        if self.is_empty():
            raise Empty("the node is None")
        answer = self._head._element
        self._head = self._head._next
        self._size -= 1
        return answer

    def top(self):
        if self.is_empty():
            raise Empty("the node is None")
        return self._head

    def find(self):
        walk = self._head._next
        while walk._next is not None:
            yield walk._element
            walk = walk._next


if __name__ == "__main__":
    link = Linkstack()
    [link.push(i) for i in range(10)]
    for i in link.find():
        print(i)

2

class Empty(Exception):
    pass


class LinkStack:
    __slots__ = "_head", "_size"

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

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

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

    def __len__(self):
        return self._size

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

    def top(self):
        if self.is_empty():
            raise Empty("the linkstack is None")
        return self._head._element

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

    def pop(self):
        if self.is_empty():
            raise Empty("the linkstack is None")
        answer = self._head._element
        self._head = self._head._next
        self._size -= 1
        return answer

    def tail(self):
        walk = self._head
        while walk is not None:
            walk = walk._next
            if walk._next is None:
                return walk

    def concat(self, item):
        temp = item.tail()
        temp._next = self._head
        self._head = item._head
        self._size += item._size


if __name__ == "__main__":
    L = LinkStack()
    M = LinkStack()
    [L.push(i) for i in range(10)]
    [M.push(i) for i in range(10, 20)]
    L.concat(M)
    print([L.pop() for i in range(20)])

3

class Empty(Exception):
    pass


class LinkStack:
    __slots__ = "_head", "_size"

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

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

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

    def __len__(self):
        return self._size

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

    def top(self):
        if self.is_empty():
            raise Empty("the linkstack is None")
        return self._head._element

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

    def pop(self):
        if self.is_empty():
            raise Empty("the linkstack is None")
        answer = self._head._element
        self._head = self._head._next
        self._size -= 1
        return answer

    def tail(self):
        walk = self._head
        while walk is not None:
            walk = walk._next
            if walk._next is None:
                return walk

    def concat(self, item):
        temp = item.tail()
        temp._next = self._head
        self._head = item._head
        self._size += item._size


def sum(stack):
    if stack.is_empty():
        return 0
    else:
        stack.pop()
        return 1 + sum(stack)


if __name__ == "__main__":
    L = LinkStack()
    M = LinkStack()
    [L.push(i) for i in range(10)]
    [M.push(i) for i in range(10, 20)]
    L.concat(M)
    print(len(L))
    print(sum(L))
    # print([L.pop() for i in range(20)])

4

import random


class Empty(Exception):
    pass


class LinkStack:
    __slots__ = "_head", "_size"

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

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

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

    def __len__(self):
        return self._size

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

    def top(self):
        if self.is_empty():
            raise Empty("the linkstack is None")
        return self._head._element

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

    def pop(self):
        if self.is_empty():
            raise Empty("the linkstack is None")
        answer = self._head._element
        self._head = self._head._next
        self._size -= 1
        return answer

    def tail(self):
        walk = self._head
        while walk is not None:
            walk = walk._next
            if walk._next is None:
                return walk

    def concat(self, item):
        temp = item.tail()
        temp._next = self._head
        self._head = item._head
        self._size += item._size

    def get_random_node(self):
        walk = self._head
        temp = []
        while walk._next is not None:
            temp.append(walk)
            walk = walk._next
        return random.choices(temp, k=2)

    def exchange(self):
        node1, node2 = self.get_random_node()
        walk = self._head
        while walk._next is not None:
            if walk._next == node1:
                new_walk = self._head
                while new_walk._next is not None:
                    if new_walk._next == node2:
                        break
                    new_walk = new_walk._next
                walk._next, node2._next, new_walk._next, node1._next = node2, node1._next, node1, node2._next  # 利用同时分配技术
                break
            walk = walk._next
        pass


def sum(stack):
    if stack.is_empty():
        return 0
    else:
        stack.pop()
        return 1 + sum(stack)


if __name__ == "__main__":
    L = LinkStack()
    M = LinkStack()
    [L.push(i) for i in range(10)]
    [M.push(i) for i in range(10, 20)]
    L.concat(M)
    print(len(L))
    print(L.exchange())
    print([L.pop() for i in range(20)])

5

class Empty(Exception):
    pass


class CircleStack:
    __slots__ = "_tail", "_size"

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

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

    def __init__(self):
        self._tail = None
        self._size = 0

    def __len__(self):
        return self._size

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

    def first(self):
        if self.is_empty():
            raise Empty("CircleStack is None")
        return self._tail._next

    def dequeue(self):
        if self.is_empty():
            raise Empty("CircleStack is None")
        answer = self._tail._next
        if self._size == 1:
            self._tail = None
        else:
            self._tail._next = answer._next
        self._size -= 1
        return answer._element

    def enqueue(self, e):
        node = self._Node(e, None)
        if self._size == 0:
            node._next = node
        else:
            node._next = self._tail._next
            self._tail._next = node
        self._tail = node
        self._size += 1

    def rotate(self, k=5):
        if self.is_empty():
            raise Empty("CircleStack is None")
        walk = self._tail
        i = 0
        while i < k and walk is not None:
            walk = walk._next
            i += 1
        self._tail = walk


if __name__ == "__main__":
    circleStack = CircleStack()
    [circleStack.enqueue(i) for i in range(10)]
    circleStack.rotatate(2)
    print(len(circleStack))
    [print(circleStack.dequeue(), end=' ') for i in range(10)]

6

import random


class Empty(Exception):
    pass


class CircleStack:
    __slots__ = "_tail", "_size"

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

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

    def __init__(self):
        self._tail = None
        self._size = 0

    def __len__(self):
        return self._size

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

    def first(self):
        if self.is_empty():
            raise Empty("CircleStack is None")
        return self._tail._next

    def dequeue(self):
        if self.is_empty():
            raise Empty("CircleStack is None")
        answer = self._tail._next
        if self._size == 1:
            self._tail = None
        else:
            self._tail._next = answer._next
        self._size -= 1
        return answer._element

    def enqueue(self, e):
        node = self._Node(e, None)
        if self._size == 0:
            node._next = node
        else:
            node._next = self._tail._next
            self._tail._next = node
        self._tail = node
        self._size += 1

    def rotate(self, k=5):
        if self.is_empty():
            raise Empty("CircleStack is None")
        walk = self._tail
        i = 0
        while i < k and walk is not None:
            walk = walk._next
            i += 1
        self._tail = walk

    def get_random_node(self):
        walk = self._tail._next
        temp = []
        while walk._next != self._tail:
            temp.append(walk)
            walk = walk._next
        node = random.choices(temp, k=1)[-1]
        node._container = self
        return node

    def validate(self, node):
        if not isinstance(node, self._Node):
            return False
        if node._container is not self:
            return False
        return True


if __name__ == "__main__":
    circleStack1 = CircleStack()
    circleStack2 = CircleStack()
    [circleStack1.enqueue(i) for i in range(10)]
    [circleStack2.enqueue(i) for i in range(10)]
    node1 = circleStack1.get_random_node()
    node2 = circleStack2.get_random_node()
    print(circleStack1.validate(node1))
    [print(circleStack1.dequeue(), end=' ') for i in range(10)]

7

class Empty(Exception):
    pass


class LinkQueue:
    """FIFO queue implementation using a singly linked list for storage."""

    __slots__ = "_head", "_tail", "_size"

    class _Node:
        """Lightweight,nonpublic class for storing a singly linked node."""
        __slots__ = "_element", "_next"  # streamline memory usage

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

    def __init__(self):
        """Create an empty queue."""
        self._head = None
        self._tail = None
        self._size = 0  # number of queue elements

    def __len__(self):
        """Return the number of elements in the queue."""
        return self._size

    def is_empty(self):
        """Return True if the queue is emtpy."""
        return self._size == 0

    def first(self):
        """Return (but do not remove) the element at the front of the queue."""
        if self.is_empty():
            raise Empty("Queue is empty")
        return self._head._element

    def dequeue(self):
        """Remove and return the first element of the queue.
        Raise Emtpy exception if the queue is empty.
        """
        if self.is_empty():
            raise Empty("Queue is empty")
        answer = self._head._element
        self._head = self._head._next
        self._size -= 1
        if self.is_empty():  # special case as queue is empty
            self._tail = None  # remove head had been the tail
        return answer

    def enqueue(self, item):
        """Add an element to the back of queue."""
        newest = self._Node(item, None)  # node will be new tail node
        if self.is_empty():
            self._head = newest  # special case : perviously empty
        else:
            self._tail._next = newest
        self._tail = newest  # update reference to tail node
        self._size += 1

    def rotate(self, k=5):
        walk = self._head
        temp = None
        i = 0
        while i < k:
            walk = walk._next
            if i == k - 1:
                temp = walk
            i += 1
        self._tail._next = self._head
        self._tail = temp
        self._head = walk


if __name__ == "__main__":
    linkQueue = LinkQueue()
    [linkQueue.enqueue(i) for i in range(10)]
    linkQueue.rotate()
    [print(linkQueue.dequeue()) for i in range(10)]

8

class Empty(Exception):
    pass


class DoublyLinkedBase:
    """A base class providing a doubly linked list representation."""

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

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

    def __init__(self):
        """Create an empty list."""
        self._header = self._Node(None, None, None)
        self._tailer = self._Node(None, None, None)
        self._header._next = self._tailer  # trailer is after header
        self._tailer._prev = self._header  # header is before trailer
        self._size = 0  # number of elements

    def __len__(self):
        """Return the number of elements in the list."""
        return self._size

    def is_empty(self):
        """Return True if list is empty."""
        return self._size == 0

    def _insert_between(self, e, predecessor, successor):
        """Add element e between two existing nodes and return new node."""
        newest = self._Node(e, predecessor, successor)
        predecessor._next = newest
        successor._prev = newest
        self._size += 1
        return newest

    def _delete_node(self, node):
        """Delete nonsentinel node from the list and return its element."""
        predecessor = node._prev
        successor = node._next
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        element = node._element  # record deleted element
        node._prev = node._next = node._element = None  # deprecate node
        return element

    def enqueue(self, item):
        if self._size == 0:
            self._insert_between(item, self._header, self._tailer)
        else:
            self._insert_between(item, self._tailer._prev, self._tailer)
        self._size += 1

    def dequeue(self):
        if self.is_empty():
            raise Empty("the doublelinked is None!")
        return self._delete_node(self._header._next)

    def midNode(self):
        walk1 = self._header._next
        walk2 = self._tailer._prev
        node = None
        while  walk1._next is not None and walk2._prev is not None:
            node = walk1
            walk1 = walk1._next
            walk2 = walk2._prev
            if walk1 == walk2:
                return node._element
            if walk1._next == walk2:
                return walk1._next._element


if __name__ == "__main__":
    doubleLink = DoublyLinkedBase()
    [doubleLink.enqueue(i) for i in range(10)]
    print(doubleLink.midNode())
    [print(doubleLink.dequeue()) for i in range(10)]

9

class Empty(Exception):
    pass


class DoublyLinkedBase:
    """A base class providing a doubly linked list representation."""

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

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

    def __init__(self):
        """Create an empty list."""
        self._header = self._Node(None, None, None)
        self._tailer = self._Node(None, None, None)
        self._header._next = self._tailer  # trailer is after header
        self._tailer._prev = self._header  # header is before trailer
        self._size = 0  # number of elements

    def __len__(self):
        """Return the number of elements in the list."""
        return self._size

    def is_empty(self):
        """Return True if list is empty."""
        return self._size == 0

    def _insert_between(self, e, predecessor, successor):
        """Add element e between two existing nodes and return new node."""
        newest = self._Node(e, predecessor, successor)
        predecessor._next = newest
        successor._prev = newest
        self._size += 1
        return newest

    def _delete_node(self, node):
        """Delete nonsentinel node from the list and return its element."""
        predecessor = node._prev
        successor = node._next
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        element = node._element  # record deleted element
        node._prev = node._next = node._element = None  # deprecate node
        return element

    def enqueue(self, item):
        if self._size == 0:
            self._insert_between(item, self._header, self._tailer)
        else:
            self._insert_between(item, self._tailer._prev, self._tailer)
        self._size += 1

    def dequeue(self):
        if self.is_empty():
            raise Empty("the doublelinked is None!")
        return self._delete_node(self._header._next)

    def midNode(self):
        walk1 = self._header._next
        walk2 = self._tailer._prev
        node = None
        while walk1._next is not None and walk2._prev is not None:
            node = walk1
            walk1 = walk1._next
            walk2 = walk2._prev
            if walk1 == walk2:
                return node._element
            if walk1._next == walk2:
                return walk1._next._element

    def concat(self, doubleLink):
        self._tailer._prev._next = doubleLink._header._next
        doubleLink._tailer._prev._next = self._tailer
        pass


if __name__ == "__main__":
    L = DoublyLinkedBase()
    M = DoublyLinkedBase()
    [L.enqueue(i) for i in range(10)]
    [M.enqueue(i) for i in range(10,20)]
    L.concat(M)
    [print(L.dequeue()) for i in range(20)]

11

class Empty(Exception):
    pass


class _DoublyLinkedBase:
    """A base class providing a doubly linked list representation."""

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

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

    def __init__(self):
        """Create an empty list."""
        self._header = self._Node(None, None, None)
        self._trailer = self._Node(None, None, None)
        self._header._next = self._trailer  # trailer is after header
        self._trailer._prev = self._header  # header is before trailer
        self._size = 0  # number of elements

    def __len__(self):
        """Return the number of elements in the list."""
        return self._size

    def is_empty(self):
        """Return True if list is empty."""
        return self._size == 0

    def _insert_between(self, e, predecessor, successor):
        """Add element e between two existing nodes and return new node."""
        newest = self._Node(e, predecessor, successor)
        predecessor._next = newest
        successor._prev = newest
        self._size += 1
        return newest

    def _delete_node(self, node):
        """Delete nonsentinel node from the list and return its element."""
        predecessor = node._prev
        successor = node._next
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        element = node._element  # record deleted element
        node._prev = node._next = node._element = None  # deprecate node
        return element


class LinkedDeque(_DoublyLinkedBase):  # note the use of inheritance
    """Double-ended queue implementation based on a doubly linked list."""

    def first(self):
        """Return (but do not remove) the element at the front of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._header._next._element  # real item just after header

    def last(self):
        """Return (but do not remove) the element at the back of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._trailer._prev._element  # readl item just before trailer

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

    def insert_last(self, e):
        """Add an element to the back of the deque."""
        self._insert_between(e, self._trailer._prev, self._trailer)  # before trailer

    def delete_first(self):
        """Remove and return the element from the front of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._header._next)  # use inherited method

    def delete_last(self):
        """Remove and return the element from the back of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._trailer._prev)  # use inherited method


class PositionalList(_DoublyLinkedBase):
    """A sequential container of elements allowing positional accress."""

    # -----------  nested Position class ------------
    class Position:
        """An abstraction representing the location of a single element."""

        def __init__(self, container, node):
            """Constructor should not be invoked by user."""
            self._container = container
            self._node = node

        def element(self):
            """Return the element stored at this Position."""
            return self._node._element

        def __eq__(self, other):
            """Return True if other is a Position representing the same location."""
            return type(other) is type(self) and other._node is self._node

        def __ne__(self, other):
            """Return True if other does not represent the same location."""
            return not (self == other)  # opposite of __eq__

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

    def _validate(self, p):
        """Return position's node ,or raise appropriate error if invalid."""
        if not isinstance(p, self.Position):
            raise TypeError("p must be proper Position type")
        if p._container is not self:
            raise ValueError("p does not belong to this container")
        if p._node._next is None:
            raise ValueError("p is no longer valid")
        return p._node

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

    def _make_position(self, node):
        """Return Position instance for given node (or None if sentinel)"""
        if node is self._header or node is self._trailer:
            return None  # boundary violation
        else:
            return self.Position(self, node)  # legitimate position

    def first(self):
        """Return the first Position in the list (or None if list is empty)."""
        return self._make_position(self._header._next)

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

    def before(self, p):
        """Return the Position just before Position p (or None if p is first)."""
        node = self._validate(p)
        return self._make_position(node._prev)

    def after(self, p):
        """Return the Position just after Position p (or None if p is last)."""
        node = self._validate(p)
        return self._make_position(node._next)

    def __iter__(self):
        """Generate a forward iteration of the elements of the list."""
        cursor = self.first()
        while cursor is not None:
            yield cursor.element()
            cursor = self.after(cursor)

    # -------------------mutators --------------------------
    # override inherited version to return Position,rather than Node
    def __insert_between(self, e, predecessor, successor):
        """Add element between existing nodes and return new Position."""
        node = super()._insert_between(e, predecessor, successor)
        return self._make_position(node)

    def add_first(self, e):
        """Insert element e at the front of the list and return new Position."""
        return self._insert_between(e, self._header, self._header._next)

    def add_last(self, e):
        """Insert element e at the back of the list and return new Postion."""
        return self.__insert_between(e, self._trailer._prev, self._trailer)

    def add_before(self, p, e):
        """Insert element e into list before Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original._prev, original)

    def add_after(self, p, e):
        """Insert element e into list after Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original, original._next)

    def delete(self, p):
        """Remove and return the element at Position p."""
        original = self._validate(p)
        return self._delete_node(original)  # inherited method returns element

    def replace(self, p, e):
        """Replace the element at Position p with e.
        Return the element formerly at Position p.
        """
        original = self._validate(p)
        old_value = original._element  # temporarily store old element
        original._element = e  # replace with new element
        return old_value  # return the old element value

    def max(self):
        temp = []
        walk = self._header._next
        while walk._next is not None:
            temp.append(walk._element)
            walk = walk._next
        return max(temp)


if __name__ == "__main__":
    positionalList = PositionalList()
    [positionalList.add_first(i) for i in range(10)]
    print(positionalList.max())

12

class Empty(Exception):
    pass


class _DoublyLinkedBase:
    """A base class providing a doubly linked list representation."""

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

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

    def __init__(self):
        """Create an empty list."""
        self._header = self._Node(None, None, None)
        self._trailer = self._Node(None, None, None)
        self._header._next = self._trailer  # trailer is after header
        self._trailer._prev = self._header  # header is before trailer
        self._size = 0  # number of elements

    def __len__(self):
        """Return the number of elements in the list."""
        return self._size

    def is_empty(self):
        """Return True if list is empty."""
        return self._size == 0

    def _insert_between(self, e, predecessor, successor):
        """Add element e between two existing nodes and return new node."""
        newest = self._Node(e, predecessor, successor)
        predecessor._next = newest
        successor._prev = newest
        self._size += 1
        return newest

    def _delete_node(self, node):
        """Delete nonsentinel node from the list and return its element."""
        predecessor = node._prev
        successor = node._next
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        element = node._element  # record deleted element
        node._prev = node._next = node._element = None  # deprecate node
        return element


class LinkedDeque(_DoublyLinkedBase):  # note the use of inheritance
    """Double-ended queue implementation based on a doubly linked list."""

    def first(self):
        """Return (but do not remove) the element at the front of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._header._next._element  # real item just after header

    def last(self):
        """Return (but do not remove) the element at the back of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._trailer._prev._element  # readl item just before trailer

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

    def insert_last(self, e):
        """Add an element to the back of the deque."""
        self._insert_between(e, self._trailer._prev, self._trailer)  # before trailer

    def delete_first(self):
        """Remove and return the element from the front of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._header._next)  # use inherited method

    def delete_last(self):
        """Remove and return the element from the back of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._trailer._prev)  # use inherited method


class PositionalList(_DoublyLinkedBase):
    """A sequential container of elements allowing positional accress."""

    # -----------  nested Position class ------------
    class Position:
        """An abstraction representing the location of a single element."""

        def __init__(self, container, node):
            """Constructor should not be invoked by user."""
            self._container = container
            self._node = node

        def element(self):
            """Return the element stored at this Position."""
            return self._node._element

        def __eq__(self, other):
            """Return True if other is a Position representing the same location."""
            return type(other) is type(self) and other._node is self._node

        def __ne__(self, other):
            """Return True if other does not represent the same location."""
            return not (self == other)  # opposite of __eq__

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

    def _validate(self, p):
        """Return position's node ,or raise appropriate error if invalid."""
        if not isinstance(p, self.Position):
            raise TypeError("p must be proper Position type")
        if p._container is not self:
            raise ValueError("p does not belong to this container")
        if p._node._next is None:
            raise ValueError("p is no longer valid")
        return p._node

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

    def _make_position(self, node):
        """Return Position instance for given node (or None if sentinel)"""
        if node is self._header or node is self._trailer:
            return None  # boundary violation
        else:
            return self.Position(self, node)  # legitimate position

    def first(self):
        """Return the first Position in the list (or None if list is empty)."""
        return self._make_position(self._header._next)

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

    def before(self, p):
        """Return the Position just before Position p (or None if p is first)."""
        node = self._validate(p)
        return self._make_position(node._prev)

    def after(self, p):
        """Return the Position just after Position p (or None if p is last)."""
        node = self._validate(p)
        return self._make_position(node._next)

    def __iter__(self):
        """Generate a forward iteration of the elements of the list."""
        cursor = self.first()
        while cursor is not None:
            yield cursor.element()
            cursor = self.after(cursor)

    # -------------------mutators --------------------------
    # override inherited version to return Position,rather than Node
    def __insert_between(self, e, predecessor, successor):
        """Add element between existing nodes and return new Position."""
        node = super()._insert_between(e, predecessor, successor)
        return self._make_position(node)

    def add_first(self, e):
        """Insert element e at the front of the list and return new Position."""
        return self._insert_between(e, self._header, self._header._next)

    def add_last(self, e):
        """Insert element e at the back of the list and return new Postion."""
        return self.__insert_between(e, self._trailer._prev, self._trailer)

    def add_before(self, p, e):
        """Insert element e into list before Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original._prev, original)

    def add_after(self, p, e):
        """Insert element e into list after Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original, original._next)

    def delete(self, p):
        """Remove and return the element at Position p."""
        original = self._validate(p)
        return self._delete_node(original)  # inherited method returns element

    def replace(self, p, e):
        """Replace the element at Position p with e.
        Return the element formerly at Position p.
        """
        original = self._validate(p)
        old_value = original._element  # temporarily store old element
        original._element = e  # replace with new element
        return old_value  # return the old element value

    # def max(self):
    #     temp = []
    #     walk = self._header._next
    #     while walk._next is not None:
    #         temp.append(walk._element)
    #         walk = walk._next
    #     return max(temp)

    def max(self):
        walk = self.first()
        value = self.first().element()
        while self.before(walk) is not None:
            if value < self.before(walk).element():
                value = self.before(walk).element()
            walk = self.before(walk)
        return value


if __name__ == "__main__":
    positionalList = PositionalList()
    [positionalList.add_first(i) for i in range(10)]
    print(positionalList.max())

13

class Empty(Exception):
    pass


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

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

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

    def __len__(self):
        return self._size

    def is_empty(self):
        return len(self) == 0

    def _insert_between(self, e, predecessor, successor):
        node = self._Node(e, predecessor, successor)
        predecessor._next = node
        successor._prev = node
        self._size += 1
        return node

    def _delete_node(self, node):
        predecessor = node._prev
        successor = node._next
        element = node._element
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        node._element = node._prev = node._next = None
        return element


class LinkDeque(doubleLinkeBase):
    def first(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._header._next._element

    def last(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._tailer._prev._element

    def insert_first(self, e):
        self._insert_between(e, self._header, self._header._next)

    def insert_last(self, e):
        self._insert_between(e, self._tailer._prev, self._tailer)

    def delete_first(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._delete_node(self._header._next)

    def delete_last(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._delete_node(self._tailer._prev)


class PositionalList(doubleLinkeBase):
    class Position:
        __slots__ = "_container", "_node"

        def __init__(self, container, node):
            self._container = container
            self._node = node

        def element(self):
            return self._node._element

        def __eq__(self, other):
            return type(other) is type(self) and other._node is self._node

        def __ne__(self, other):
            return not (self == other)

    def _validate(self, p):
        if not isinstance(p, self.Position):
            raise TypeError("p must be proper Position type")
        if p._container is not self:
            raise ValueError("p does not belong to this container")
        if p._node._next is None:
            raise ValueError("p is no longer valid")
        return p._node

    def _make_position(self, node):
        if node is self._header or node is self._tailer:
            return None
        else:
            return self.Position(self, node)

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

    def last(self):
        return self._make_position(self._tailer._prev)

    def before(self, p):
        node = self._validate(p)
        return self._make_position(node._prev)

    def after(self, p):
        node = self._validate(p)
        return self._make_position(node._next)

    def __iter__(self):
        cursor = self.first()
        while cursor is not None:
            yield cursor.element()
            cursor = self.after(cursor)

    def __insert_between(self, e, predecessor, successor):
        node = super()._insert_between(e, predecessor, successor)
        return self._make_position(node)

    def add_first(self, p):
        return self.__insert_between(p, self._header, self._header._next)

    def add_last(self, p):
        return self.__insert_between(p, self._tailer._prev, self._tailer)

    def add_before(self, p, e):
        node = self._validate(p)
        return self.__insert_between(e, node._prev, node)

    def add_after(self, p, e):
        node = self._validate(p)
        return self.__insert_between(e, node, node._next)

    def delete(self, p):
        node = self._validate(p)
        return self._delete_node(node)

    def replace(self, p, e):
        node = self._validate(p)
        old_value = node._element
        node._element = e
        return old_value

    def find(self, e):
        count = 0
        walk = self.first()
        while self.after(walk) is not None:
            if walk.element() == e:
                return count
            count += 1
            walk = self.after(walk)
        else:
            return None


if __name__ == "__main__":
    positionalList = PositionalList()
    [positionalList.add_first(i) for i in range(10)]
    positionalList.replace(positionalList.first(), 5)
    print(positionalList.first().element())
    print(positionalList.find(5))

14

class Empty(Exception):
    pass


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

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

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

    def __len__(self):
        return self._size

    def is_empty(self):
        return len(self) == 0

    def _insert_between(self, e, predecessor, successor):
        node = self._Node(e, predecessor, successor)
        predecessor._next = node
        successor._prev = node
        self._size += 1
        return node

    def _delete_node(self, node):
        predecessor = node._prev
        successor = node._next
        element = node._element
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        node._element = node._prev = node._next = None
        return element


class LinkDeque(doubleLinkeBase):
    def first(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._header._next._element

    def last(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._tailer._prev._element

    def insert_first(self, e):
        self._insert_between(e, self._header, self._header._next)

    def insert_last(self, e):
        self._insert_between(e, self._tailer._prev, self._tailer)

    def delete_first(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._delete_node(self._header._next)

    def delete_last(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._delete_node(self._tailer._prev)


class PositionalList(doubleLinkeBase):
    class Position:
        __slots__ = "_container", "_node"

        def __init__(self, container, node):
            self._container = container
            self._node = node

        def element(self):
            return self._node._element

        def __eq__(self, other):
            return type(other) is type(self) and other._node is self._node

        def __ne__(self, other):
            return not (self == other)

    def __int__(self):
        self._cursor = self._header._next

    def _validate(self, p):
        if not isinstance(p, self.Position):
            raise TypeError("p must be proper Position type")
        if p._container is not self:
            raise ValueError("p does not belong to this container")
        if p._node._next is None:
            raise ValueError("p is no longer valid")
        return p._node

    def _make_position(self, node):
        if node is self._header or node is self._tailer:
            return None
        else:
            return self.Position(self, node)

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

    def last(self):
        return self._make_position(self._tailer._prev)

    def before(self, p):
        node = self._validate(p)
        return self._make_position(node._prev)

    def after(self, p):
        node = self._validate(p)
        return self._make_position(node._next)

    def __iter__(self):
        cursor = self.first()
        while cursor is not None:
            yield cursor.element()
            cursor = self.after(cursor)

    def __insert_between(self, e, predecessor, successor):
        node = super()._insert_between(e, predecessor, successor)
        return self._make_position(node)

    def add_first(self, p):
        return self.__insert_between(p, self._header, self._header._next)

    def add_last(self, p):
        return self.__insert_between(p, self._tailer._prev, self._tailer)

    def add_before(self, p, e):
        node = self._validate(p)
        return self.__insert_between(e, node._prev, node)

    def add_after(self, p, e):
        node = self._validate(p)
        return self.__insert_between(e, node, node._next)

    def delete(self, p):
        node = self._validate(p)
        return self._delete_node(node)

    def replace(self, p, e):
        node = self._validate(p)
        old_value = node._element
        node._element = e
        return old_value

    def find_count(self, cursor, element):
        if cursor is None:
            return 0
        else:
            if cursor.element() == element:
                return 1
            else:
                cursor = self.after(cursor)
                total = self.find_count(cursor, element)
                return 1 + total

    def find(self, e):
        walk = self.first()
        count = self.find_count(walk, e)
        if count == 0:
            return None
        else:
            return count-1


if __name__ == "__main__":
    positionalList = PositionalList()
    [positionalList.add_first(i) for i in range(10)]
    print(positionalList.first().element())
    print(positionalList.find(0))

15

class Empty(Exception):
    pass


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

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

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

    def __len__(self):
        return self._size

    def is_empty(self):
        return len(self) == 0

    def _insert_between(self, e, predecessor, successor):
        node = self._Node(e, predecessor, successor)
        predecessor._next = node
        successor._prev = node
        self._size += 1
        return node

    def _delete_node(self, node):
        predecessor = node._prev
        successor = node._next
        element = node._element
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        node._element = node._prev = node._next = None
        return element


class LinkDeque(doubleLinkeBase):
    def first(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._header._next._element

    def last(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._tailer._prev._element

    def insert_first(self, e):
        self._insert_between(e, self._header, self._header._next)

    def insert_last(self, e):
        self._insert_between(e, self._tailer._prev, self._tailer)

    def delete_first(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._delete_node(self._header._next)

    def delete_last(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._delete_node(self._tailer._prev)


class PositionalList(doubleLinkeBase):
    class Position:
        __slots__ = "_container", "_node"

        def __init__(self, container, node):
            self._container = container
            self._node = node

        def element(self):
            return self._node._element

        def __eq__(self, other):
            return type(other) is type(self) and other._node is self._node

        def __ne__(self, other):
            return not (self == other)

    def __int__(self):
        self._cursor = self._header._next

    def _validate(self, p):
        if not isinstance(p, self.Position):
            raise TypeError("p must be proper Position type")
        if p._container is not self:
            raise ValueError("p does not belong to this container")
        if p._node._next is None:
            raise ValueError("p is no longer valid")
        return p._node

    def _make_position(self, node):
        if node is self._header or node is self._tailer:
            return None
        else:
            return self.Position(self, node)

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

    def last(self):
        return self._make_position(self._tailer._prev)

    def before(self, p):
        node = self._validate(p)
        return self._make_position(node._prev)

    def after(self, p):
        node = self._validate(p)
        return self._make_position(node._next)

    def __iter__(self):
        cursor = self.first()
        while cursor is not None:
            yield cursor.element()
            cursor = self.after(cursor)

    def __insert_between(self, e, predecessor, successor):
        node = super()._insert_between(e, predecessor, successor)
        return self._make_position(node)

    def add_first(self, p):
        return self.__insert_between(p, self._header, self._header._next)

    def add_last(self, p):
        return self.__insert_between(p, self._tailer._prev, self._tailer)

    def add_before(self, p, e):
        node = self._validate(p)
        return self.__insert_between(e, node._prev, node)

    def add_after(self, p, e):
        node = self._validate(p)
        return self.__insert_between(e, node, node._next)

    def delete(self, p):
        node = self._validate(p)
        return self._delete_node(node)

    def replace(self, p, e):
        node = self._validate(p)
        old_value = node._element
        node._element = e
        return old_value

    def find_count(self, cursor, element):
        if cursor is None:
            return 0
        else:
            if cursor.element() == element:
                return 1
            else:
                cursor = self.after(cursor)
                total = self.find_count(cursor, element)
                return 1 + total

    def find(self, e):
        walk = self.first()
        count = self.find_count(walk, e)
        if count == 0:
            return None
        else:
            return count - 1

    def __reversed__(self):
        cursor = self.last()
        while cursor is not None:
            yield cursor.element()
            cursor = self.before(cursor)


if __name__ == "__main__":
    positionalList = PositionalList()
    [positionalList.add_first(i) for i in range(10)]
    for element in positionalList.__reversed__():
        print(element)

16

class Empty(Exception):
    pass


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

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

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

    def __len__(self):
        return self._size

    def is_empty(self):
        return len(self) == 0

    def _insert_between(self, e, predecessor, successor):
        node = self._Node(e, predecessor, successor)
        predecessor._next = node
        successor._prev = node
        self._size += 1
        return node

    def _delete_node(self, node):
        predecessor = node._prev
        successor = node._next
        element = node._element
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        node._element = node._prev = node._next = None
        return element


class LinkDeque(doubleLinkeBase):
    def first(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._header._next._element

    def last(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._tailer._prev._element

    def insert_first(self, e):
        self._insert_between(e, self._header, self._header._next)

    def insert_last(self, e):
        self._insert_between(e, self._tailer._prev, self._tailer)

    def delete_first(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._delete_node(self._header._next)

    def delete_last(self):
        if self.is_empty():
            raise Empty("the LinkDeque is None")
        return self._delete_node(self._tailer._prev)


class PositionalList(doubleLinkeBase):
    class Position:
        __slots__ = "_container", "_node"

        def __init__(self, container, node):
            self._container = container
            self._node = node

        def element(self):
            return self._node._element

        def __eq__(self, other):
            return type(other) is type(self) and other._node is self._node

        def __ne__(self, other):
            return not (self == other)

    def __int__(self):
        self._cursor = self._header._next

    def _validate(self, p):
        if not isinstance(p, self.Position):
            raise TypeError("p must be proper Position type")
        if p._container is not self:
            raise ValueError("p does not belong to this container")
        if p._node._next is None:
            raise ValueError("p is no longer valid")
        return p._node

    def _make_position(self, node):
        if node is self._header or node is self._tailer:
            return None
        else:
            return self.Position(self, node)

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

    def last(self):
        return self._make_position(self._tailer._prev)

    def before(self, p):
        node = self._validate(p)
        return self._make_position(node._prev)

    def after(self, p):
        node = self._validate(p)
        return self._make_position(node._next)

    def __iter__(self):
        cursor = self.first()
        while cursor is not None:
            yield cursor.element()
            cursor = self.after(cursor)

    def __insert_between(self, e, predecessor, successor):
        node = super()._insert_between(e, predecessor, successor)
        return self._make_position(node)

    def add_first(self, p):
        return self.__insert_between(p, self._header, self._header._next)

    def add_last(self, p):
        return self.add_after(self.last(),p)

    def add_before(self, p, e):
        return self.add_after(p,e)

    def add_after(self, p, e):
        node = self._validate(p)
        return self.__insert_between(e, node, node._next)

    def delete(self, p):
        node = self._validate(p)
        return self._delete_node(node)

    def replace(self, p, e):
        node = self._validate(p)
        old_value = node._element
        node._element = e
        return old_value

    def find_count(self, cursor, element):
        if cursor is None:
            return 0
        else:
            if cursor.element() == element:
                return 1
            else:
                cursor = self.after(cursor)
                total = self.find_count(cursor, element)
                return 1 + total

    def find(self, e):
        walk = self.first()
        count = self.find_count(walk, e)
        if count == 0:
            return None
        else:
            return count - 1

    def __reversed__(self):
        cursor = self.last()
        while cursor is not None:
            yield cursor.element()
            cursor = self.before(cursor)


if __name__ == "__main__":
    positionalList = PositionalList()
    [positionalList.add_first(i) for i in range(10)]
    positionalList.add_last(100)
    positionalList.add_before(positionalList.first(),99)
    [print(positionalList.delete(positionalList.last())) for i in range(11)]


17

class Empty(Exception):
    pass


class _DoublyLinkedBase:
    """A base class providing a doubly linked list representation."""

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

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

    def __init__(self):
        """Create an empty list."""
        self._header = self._Node(None, None, None)
        self._trailer = self._Node(None, None, None)
        self._header._next = self._trailer  # trailer is after header
        self._trailer._prev = self._header  # header is before trailer
        self._size = 0  # number of elements

    def __len__(self):
        """Return the number of elements in the list."""
        return self._size

    def is_empty(self):
        """Return True if list is empty."""
        return self._size == 0

    def _insert_between(self, e, predecessor, successor):
        """Add element e between two existing nodes and return new node."""
        newest = self._Node(e, predecessor, successor)
        predecessor._next = newest
        successor._prev = newest
        self._size += 1
        return newest

    def _delete_node(self, node):
        """Delete nonsentinel node from the list and return its element."""
        predecessor = node._prev
        successor = node._next
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        element = node._element  # record deleted element
        node._prev = node._next = node._element = None  # deprecate node
        return element


class LinkedDeque(_DoublyLinkedBase):  # note the use of inheritance
    """Double-ended queue implementation based on a doubly linked list."""

    def first(self):
        """Return (but do not remove) the element at the front of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._header._next._element  # real item just after header

    def last(self):
        """Return (but do not remove) the element at the back of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._trailer._prev._element  # readl item just before trailer

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

    def insert_last(self, e):
        """Add an element to the back of the deque."""
        self._insert_between(e, self._trailer._prev, self._trailer)  # before trailer

    def delete_first(self):
        """Remove and return the element from the front of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._header._next)  # use inherited method

    def delete_last(self):
        """Remove and return the element from the back of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._trailer._prev)  # use inherited method


class PositionalList(_DoublyLinkedBase):
    """A sequential container of elements allowing positional accress."""

    # -----------  nested Position class ------------
    class Position:
        """An abstraction representing the location of a single element."""

        def __init__(self, container, node):
            """Constructor should not be invoked by user."""
            self._container = container
            self._node = node

        def element(self):
            """Return the element stored at this Position."""
            return self._node._element

        def __eq__(self, other):
            """Return True if other is a Position representing the same location."""
            return type(other) is type(self) and other._node is self._node

        def __ne__(self, other):
            """Return True if other does not represent the same location."""
            return not (self == other)  # opposite of __eq__

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

    def _validate(self, p):
        """Return position's node ,or raise appropriate error if invalid."""
        if not isinstance(p, self.Position):
            raise TypeError("p must be proper Position type")
        if p._container is not self:
            raise ValueError("p does not belong to this container")
        if p._node._next is None:
            raise ValueError("p is no longer valid")
        return p._node

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

    def _make_position(self, node):
        """Return Position instance for given node (or None if sentinel)"""
        if node is self._header or node is self._trailer:
            return None  # boundary violation
        else:
            return self.Position(self, node)  # legitimate position

    def first(self):
        """Return the first Position in the list (or None if list is empty)."""
        return self._make_position(self._header._next)

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

    def before(self, p):
        """Return the Position just before Position p (or None if p is first)."""
        node = self._validate(p)
        return self._make_position(node._prev)

    def after(self, p):
        """Return the Position just after Position p (or None if p is last)."""
        node = self._validate(p)
        return self._make_position(node._next)

    def __iter__(self):
        """Generate a forward iteration of the elements of the list."""
        cursor = self.first()
        while cursor is not None:
            yield cursor.element()
            cursor = self.after(cursor)

    # -------------------mutators --------------------------
    # override inherited version to return Position,rather than Node
    def __insert_between(self, e, predecessor, successor):
        """Add element between existing nodes and return new Position."""
        node = super()._insert_between(e, predecessor, successor)
        return self._make_position(node)

    def add_first(self, e):
        """Insert element e at the front of the list and return new Position."""
        return self._insert_between(e, self._header, self._header._next)

    def add_last(self, e):
        """Insert element e at the back of the list and return new Postion."""
        return self.__insert_between(e, self._trailer._prev, self._trailer)

    def add_before(self, p, e):
        """Insert element e into list before Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original._prev, original)

    def add_after(self, p, e):
        """Insert element e into list after Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original, original._next)

    def delete(self, p):
        """Remove and return the element at Position p."""
        original = self._validate(p)
        return self._delete_node(original)  # inherited method returns element

    def replace(self, p, e):
        """Replace the element at Position p with e.
        Return the element formerly at Position p.
        """
        original = self._validate(p)
        old_value = original._element  # temporarily store old element
        original._element = e  # replace with new element
        return old_value  # return the old element value

    def move_to_front(self, p):
        walk = self.first()
        while walk is not None:
            if walk.element() == p:
                break
            walk = self.after(walk)
        else:
            raise ValueError("index is not valid")
        element = self.delete(walk)
        self.add_first(element)


if __name__ == "__main__":
    positialList = PositionalList()
    [positialList.add_last(i) for i in range(10,20)]
    positialList.move_to_front(12)
    [print(positialList.delete(positialList.first()),end=' ') for i in range(9)]
    pass

18

class Empty(Exception):
    pass


class _DoublyLinkedBase:
    """A base class providing a doubly linked list representation."""

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

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

    def __init__(self):
        """Create an empty list."""
        self._header = self._Node(None, None, None)
        self._trailer = self._Node(None, None, None)
        self._header._next = self._trailer  # trailer is after header
        self._trailer._prev = self._header  # header is before trailer
        self._size = 0  # number of elements

    def __len__(self):
        """Return the number of elements in the list."""
        return self._size

    def is_empty(self):
        """Return True if list is empty."""
        return self._size == 0

    def _insert_between(self, e, predecessor, successor):
        """Add element e between two existing nodes and return new node."""
        newest = self._Node(e, predecessor, successor)
        predecessor._next = newest
        successor._prev = newest
        self._size += 1
        return newest

    def _delete_node(self, node):
        """Delete nonsentinel node from the list and return its element."""
        predecessor = node._prev
        successor = node._next
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        element = node._element  # record deleted element
        node._prev = node._next = node._element = None  # deprecate node
        return element


class LinkedDeque(_DoublyLinkedBase):  # note the use of inheritance
    """Double-ended queue implementation based on a doubly linked list."""

    def first(self):
        """Return (but do not remove) the element at the front of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._header._next._element  # real item just after header

    def last(self):
        """Return (but do not remove) the element at the back of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._trailer._prev._element  # readl item just before trailer

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

    def insert_last(self, e):
        """Add an element to the back of the deque."""
        self._insert_between(e, self._trailer._prev, self._trailer)  # before trailer

    def delete_first(self):
        """Remove and return the element from the front of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._header._next)  # use inherited method

    def delete_last(self):
        """Remove and return the element from the back of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._trailer._prev)  # use inherited method


class PositionalList(_DoublyLinkedBase):
    """A sequential container of elements allowing positional accress."""

    # -----------  nested Position class ------------
    class Position:
        """An abstraction representing the location of a single element."""

        def __init__(self, container, node):
            """Constructor should not be invoked by user."""
            self._container = container
            self._node = node

        def element(self):
            """Return the element stored at this Position."""
            return self._node._element

        def __eq__(self, other):
            """Return True if other is a Position representing the same location."""
            return type(other) is type(self) and other._node is self._node

        def __ne__(self, other):
            """Return True if other does not represent the same location."""
            return not (self == other)  # opposite of __eq__

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

    def _validate(self, p):
        """Return position's node ,or raise appropriate error if invalid."""
        if not isinstance(p, self.Position):
            raise TypeError("p must be proper Position type")
        if p._container is not self:
            raise ValueError("p does not belong to this container")
        if p._node._next is None:
            raise ValueError("p is no longer valid")
        return p._node

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

    def _make_position(self, node):
        """Return Position instance for given node (or None if sentinel)"""
        if node is self._header or node is self._trailer:
            return None  # boundary violation
        else:
            return self.Position(self, node)  # legitimate position

    def first(self):
        """Return the first Position in the list (or None if list is empty)."""
        return self._make_position(self._header._next)

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

    def before(self, p):
        """Return the Position just before Position p (or None if p is first)."""
        node = self._validate(p)
        return self._make_position(node._prev)

    def after(self, p):
        """Return the Position just after Position p (or None if p is last)."""
        node = self._validate(p)
        return self._make_position(node._next)

    def __iter__(self):
        """Generate a forward iteration of the elements of the list."""
        cursor = self.first()
        while cursor is not None:
            yield cursor.element()
            cursor = self.after(cursor)

    # -------------------mutators --------------------------
    # override inherited version to return Position,rather than Node
    def __insert_between(self, e, predecessor, successor):
        """Add element between existing nodes and return new Position."""
        node = super()._insert_between(e, predecessor, successor)
        return self._make_position(node)

    def add_first(self, e):
        """Insert element e at the front of the list and return new Position."""
        return self._insert_between(e, self._header, self._header._next)

    def add_last(self, e):
        """Insert element e at the back of the list and return new Postion."""
        return self.__insert_between(e, self._trailer._prev, self._trailer)

    def add_before(self, p, e):
        """Insert element e into list before Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original._prev, original)

    def add_after(self, p, e):
        """Insert element e into list after Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original, original._next)

    def delete(self, p):
        """Remove and return the element at Position p."""
        original = self._validate(p)
        return self._delete_node(original)  # inherited method returns element

    def replace(self, p, e):
        """Replace the element at Position p with e.
        Return the element formerly at Position p.
        """
        original = self._validate(p)
        old_value = original._element  # temporarily store old element
        original._element = e  # replace with new element
        return old_value  # return the old element value


class FavoritesList:
    """List of elements ordered from most frequently accessed to least."""

    # ---------------nested _Item class ----------
    class _Item:
        __slots__ = "_value", "_count"  # streamling memory usage

        def __init__(self, e):
            self._value = e  # the user's element
            self._count = 0  # access count initially zero

    # --------nonpublic utilities -------------------------
    def _find_position(self, e):
        """Search for element e and return its Position(or None if not found)."""
        walk = self._data.first()
        while walk is not None and walk.element()._value != e:
            walk = self._data.after(walk)
        return walk

    def _move_up(self, p):
        """Move item at Position p earlier in the list based on access count."""
        if p != self._data.first():
            cnt = p.element()._count
            walk = self._data.before(p)
            if cnt > walk.element()._count:  # must shift forward
                while walk != self._data.first() and cnt > self._data.before(walk).element()._count:
                    walk = self._data.before(walk)
                self._data.add_before(walk, self._data.delete(p))  # delete/reinsert

    def __init__(self):
        """Create an empty list of favorites."""
        self._data = PositionalList()

    def __len__(self):
        """Return number of entries on favorites list"""
        return len(self._data)

    def is_empty(self):
        """Return True if list is empty."""
        return len(self._data) == 0

    def access(self, e):
        """Access element e,thereby increasing its access count."""
        p = self._find_position(e)  # try to locate existing element
        if p is None:
            p = self._data.add_last(self._Item(e))  # if new ,place at end
        p.element()._count += 1  # always increment count
        self._move_up(p)  # consider moving forward

    def remove(self, e):
        """Remove element e from the list of favorites."""
        p = self._find_position(e)  # try to locate existing element
        if p is not None:
            self._data.delete(p)  # delete,if fount

    def top(self, k):
        """Generate sequence of top k elements in terms of access count."""
        if not 1 <= k <= len(self):
            raise ValueError("Illegal value for k")
        walk = self._data.first()
        for j in range(k):
            item = walk.element()  # element of list is _Item
            yield item._value  # report user's element
            walk = self._data.after(walk)


if __name__ == "__main__":
    favoritelist = FavoritesList()
    favoritelist.access('a')
    favoritelist.access('b')
    favoritelist.access('c')
    favoritelist.access('d')
    favoritelist.access('e')
    favoritelist.access('f')
    favoritelist.access('a')
    favoritelist.access('c')
    favoritelist.access('f')
    favoritelist.access('b')
    favoritelist.access('d')
    favoritelist.access('e')
    for result in favoritelist.top(5):
        print(result,end=' ')

20

class Empty(Exception):
    pass


class _DoublyLinkedBase:
    """A base class providing a doubly linked list representation."""

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

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

    def __init__(self):
        """Create an empty list."""
        self._header = self._Node(None, None, None)
        self._trailer = self._Node(None, None, None)
        self._header._next = self._trailer  # trailer is after header
        self._trailer._prev = self._header  # header is before trailer
        self._size = 0  # number of elements

    def __len__(self):
        """Return the number of elements in the list."""
        return self._size

    def is_empty(self):
        """Return True if list is empty."""
        return self._size == 0

    def _insert_between(self, e, predecessor, successor):
        """Add element e between two existing nodes and return new node."""
        newest = self._Node(e, predecessor, successor)
        predecessor._next = newest
        successor._prev = newest
        self._size += 1
        return newest

    def _delete_node(self, node):
        """Delete nonsentinel node from the list and return its element."""
        predecessor = node._prev
        successor = node._next
        predecessor._next = successor
        successor._prev = predecessor
        self._size -= 1
        element = node._element  # record deleted element
        node._prev = node._next = node._element = None  # deprecate node
        return element


class LinkedDeque(_DoublyLinkedBase):  # note the use of inheritance
    """Double-ended queue implementation based on a doubly linked list."""

    def first(self):
        """Return (but do not remove) the element at the front of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._header._next._element  # real item just after header

    def last(self):
        """Return (but do not remove) the element at the back of the deque."""
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._trailer._prev._element  # readl item just before trailer

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

    def insert_last(self, e):
        """Add an element to the back of the deque."""
        self._insert_between(e, self._trailer._prev, self._trailer)  # before trailer

    def delete_first(self):
        """Remove and return the element from the front of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._header._next)  # use inherited method

    def delete_last(self):
        """Remove and return the element from the back of the deque.
        Raise Empty exception if the deque is empty.
        """
        if self.is_empty():
            raise Empty("Deque is empty")
        return self._delete_node(self._trailer._prev)  # use inherited method


class PositionalList(_DoublyLinkedBase):
    """A sequential container of elements allowing positional accress."""

    # -----------  nested Position class ------------
    class Position:
        """An abstraction representing the location of a single element."""

        def __init__(self, container, node):
            """Constructor should not be invoked by user."""
            self._container = container
            self._node = node

        def element(self):
            """Return the element stored at this Position."""
            return self._node._element

        def __eq__(self, other):
            """Return True if other is a Position representing the same location."""
            return type(other) is type(self) and other._node is self._node

        def __ne__(self, other):
            """Return True if other does not represent the same location."""
            return not (self == other)  # opposite of __eq__

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

    def _validate(self, p):
        """Return position's node ,or raise appropriate error if invalid."""
        if not isinstance(p, self.Position):
            raise TypeError("p must be proper Position type")
        if p._container is not self:
            raise ValueError("p does not belong to this container")
        if p._node._next is None:
            raise ValueError("p is no longer valid")
        return p._node

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

    def _make_position(self, node):
        """Return Position instance for given node (or None if sentinel)"""
        if node is self._header or node is self._trailer:
            return None  # boundary violation
        else:
            return self.Position(self, node)  # legitimate position

    def first(self):
        """Return the first Position in the list (or None if list is empty)."""
        return self._make_position(self._header._next)

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

    def before(self, p):
        """Return the Position just before Position p (or None if p is first)."""
        node = self._validate(p)
        return self._make_position(node._prev)

    def after(self, p):
        """Return the Position just after Position p (or None if p is last)."""
        node = self._validate(p)
        return self._make_position(node._next)

    def __iter__(self):
        """Generate a forward iteration of the elements of the list."""
        cursor = self.first()
        while cursor is not None:
            yield cursor.element()
            cursor = self.after(cursor)

    # -------------------mutators --------------------------
    # override inherited version to return Position,rather than Node
    def __insert_between(self, e, predecessor, successor):
        """Add element between existing nodes and return new Position."""
        node = super()._insert_between(e, predecessor, successor)
        return self._make_position(node)

    def add_first(self, e):
        """Insert element e at the front of the list and return new Position."""
        return self._insert_between(e, self._header, self._header._next)

    def add_last(self, e):
        """Insert element e at the back of the list and return new Postion."""
        return self.__insert_between(e, self._trailer._prev, self._trailer)

    def add_before(self, p, e):
        """Insert element e into list before Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original._prev, original)

    def add_after(self, p, e):
        """Insert element e into list after Position p and return new Position."""
        original = self._validate(p)
        return self._insert_between(e, original, original._next)

    def delete(self, p):
        """Remove and return the element at Position p."""
        original = self._validate(p)
        return self._delete_node(original)  # inherited method returns element

    def replace(self, p, e):
        """Replace the element at Position p with e.
        Return the element formerly at Position p.
        """
        original = self._validate(p)
        old_value = original._element  # temporarily store old element
        original._element = e  # replace with new element
        return old_value  # return the old element value


class FavoritesList:
    """List of elements ordered from most frequently accessed to least."""

    # ---------------nested _Item class ----------
    class _Item:
        __slots__ = "_value", "_count"  # streamling memory usage

        def __init__(self, e):
            self._value = e  # the user's element
            self._count = 0  # access count initially zero

    # --------nonpublic utilities -------------------------
    def _find_position(self, e):
        """Search for element e and return its Position(or None if not found)."""
        walk = self._data.first()
        while walk is not None and walk.element()._value != e:
            walk = self._data.after(walk)
        return walk

    def _move_up(self, p):
        """Move item at Position p earlier in the list based on access count."""
        if p != self._data.first():
            cnt = p.element()._count
            walk = self._data.before(p)
            if cnt > walk.element()._count:  # must shift forward
                while walk != self._data.first() and cnt > self._data.before(walk).element()._count:
                    walk = self._data.before(walk)
                self._data.add_before(walk, self._data.delete(p))  # delete/reinsert

    def __init__(self):
        """Create an empty list of favorites."""
        self._data = PositionalList()

    def __len__(self):
        """Return number of entries on favorites list"""
        return len(self._data)

    def is_empty(self):
        """Return True if list is empty."""
        return len(self._data) == 0

    def access(self, e):
        """Access element e,thereby increasing its access count."""
        p = self._find_position(e)  # try to locate existing element
        if p is None:
            p = self._data.add_last(self._Item(e))  # if new ,place at end
        p.element()._count += 1  # always increment count
        self._move_up(p)  # consider moving forward

    def remove(self, e):
        """Remove element e from the list of favorites."""
        p = self._find_position(e)  # try to locate existing element
        if p is not None:
            self._data.delete(p)  # delete,if fount

    def top(self, k):
        """Generate sequence of top k elements in terms of access count."""
        if not 1 <= k <= len(self):
            raise ValueError("Illegal value for k")
        walk = self._data.first()
        for j in range(k):
            item = walk.element()  # element of list is _Item
            yield item._value  # report user's element
            walk = self._data.after(walk)

    def reversed(self):
        walk = self._data.first()
        temp = PositionalList()
        while walk is not  None:
            temp.add_first(walk.element())
            walk = self._data.after(walk)
        self._data = temp


if __name__ == "__main__":
    favoritelist = FavoritesList()
    favoritelist.access('a')
    favoritelist.access('b')
    favoritelist.access('c')
    favoritelist.reversed()
    for value in favoritelist.top(3):
        print(value,end=' ')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

北漂的阿狸

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

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

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

打赏作者

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

抵扣说明:

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

余额充值