python数据结构学习笔记-4-链表

来源:互联网 发布:java界的圣经 编辑:程序博客网 时间:2024/05/09 15:53

链表

本章内容易懂,书上有图解说明和完整代码,记录下来供参考就好了。

单链表实现堆栈

class Empty(Exception):    passclass LinkedStack:    """LIFO Stack implementation using a singly linked list for storage."""    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 stack."""        self._head = None                          #reference to the head node        self._size = 0                             #number of stack elements    def __len__(self):        """Return the number of elements in the stack."""        return self._size    def is_empty(self):        """Return True if the stack is empty."""        return self._size == 0    def push(self,e):        """Add element e to the top of the stack."""        self._head = self._Node(e,self._head)          #create and linked a new node        self._size += 1    def top(self):        """Return (but do not remove) the element at the top of the stack.        Raise Empty exception if the stack is empty.        """        if self.is_empty():            raise Empty('Stack is empty')        return self._head._element    def pop(self):        """Remove and return the element from the top of the stack(i.e., LIFO).        Raise Empty exception if the stack is empty.        """        if self.is_empty():            raise Empty('Stack is empty')        answer = self._head._element        self._head = self._head._next                        #bypass the fromer top node        self._size -= 1        return answer

单链表实现队列

class LinkedQueue:    """FIFO queue implementation using a singly linked list for storage."""    class _Node:        """Lightweight, nonpublic class for storing a singly lined 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 empty."""        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                 #front aligned with head of list    def dequeue(self):        """Remove and return the first element of the queue(i.e.,FIFO).            Raise Empty exception if the queue is empty.        """        if self.is_empty():            raise Empty('Queue is empty')        anwser = self._head._element        self._head = self._head._next        self._size -= 1        if self.is_empty():                             #special case as queue is empty            self._tail = None                           #removed head had been the tail        return answer    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():            self._head = newest                        #special case: previously empty        else:            self._tail._next = newest        self._tail = newest                           #updater reference to tail node        self._size += 1

循环队列(首尾相连)


class CircularQueue:    """Queue implementation using circularly linked list for storage."""    class _Node:        """Lightweight, nonpublic class for storing a singly lined 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._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 True if the queue is empty."""        return self._size == 0    def first(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('Queue is empty')        head = self._tail._next        return head._element    def dequeue(self):        """Remove and return the first element of the queue(i.e., FIFO).        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                # old tail points to new node        self._tail = newest                            # new node becomes the tail        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

双向链表


基类:_DoublyLinkedBase

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            # streamline memory        def __init__(self, element, prev, next):   # initialize node's fields            self._element = element                #user's element            self._prev = prev                      # previous node reference            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) # linked to neighbors        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                                          # return deleted 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):        """Retrun (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       #real item just before trailer        def insert_first(self,e):        """Add an element to the front of the deque."""        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.        Raise Empty exception if the deque is empty.        """                if self.is_empty():            rasie Empty("Deque is empty")        return self._delete_node(self._trailer._prev)   #use inherited method        class PosintionalList(_DoublyLinkedBase):    """A sequential container of elements allowing positional access."""    #---------- 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 elemnt(self):            """Return the element stored at this Positiong."""            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 is 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 approriate error if invalid."""            if not isinstace(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:         #convention for deprecated nodes                raise ValueError('p is no longer valid')            return p._node                def _make_position(self, node):            """Return Position instance for given node(or None if sentinel)."""            if node if self._header or node is self._trailer:                return None                           #boundary violation            else:                return self.Position(self, node)      #legitimate position                #----------- accessors ----------------------        def first(self):            """Return the first Position in the list(or None if list ie 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_postion(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_positiong(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 Position."""            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,e):            """Insert element e into list after Position p and return new Position."""            original = self._validate(p)            return self._insert_between(e,original, origiane._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 Positin p.            """            original = self._validate(p)            old_value = original._element      #temporary store old element            original._element = e              #replace with new element            return old_value                   #return the old element value
0 0