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

链表

本章内容易懂,书上有图解说明和完整代码,记录下来供参考就好了。
python数据结构学习笔记-4-链表_第1张图片

单链表实现堆栈

class Empty(Exception):
    pass

class 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

循环队列(首尾相连)

python数据结构学习笔记-4-链表_第2张图片
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

你可能感兴趣的:(数据结构,链表,python)