我只是书的搬运工。
栈和list有很大相似之处,所以实现起来简单一些。
class Empty(Exception):
"""Error attempting to access an element from an empty container."""
pass
class ArrayStack:
"""LIFO Stack implementation using a Pythons list as underlying storage."""
def __init__(self):
"""Create an empty stack."""
self._data = []
def __len__(self):
"""Returns the number of elements in the stack."""
return len(self._data)
def is_empty(self):
"""Return True if the stack is empty."""
return len(self._data)==0
def push(self,e):
"""Add element e to the top of the stack."""
self._data.append(e)
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._data[-1]
def pop(self):
"""Remove and return the element from the top of the stack.
Raise Empty exception if the stack is empty.
"""
if self.is_empty():
raise Empty('Stack is empty')
return self._data.pop()
队列的实现稍微复杂一些,如果要用跟栈相似的方法,dequeue要用pop(0),时间是线性而不是常数(这由list的pop机制决定)。为避免这种情况,书上用了一个循环列表。
class Empty(Exception):
"""Error attempting to access an element from an empty container."""
pass
class ArrayQueue:
"""FIFO queue implementation using a Python list as underlying storage."""
DEFAULT_CAPACITY = 10
def __init__(self):
"""Create an empty queue."""
self._data = [None]*ArrayQueue.DEFAULT_CAPACITY
self._size = 0
self._front = 0
def __len__(self):
"""Return the number of elements in the queue."""
return self._size
def is_empty(self):
"""Return True is 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')
return self._data[self._front]
def dequeue(self):
"""Remeove and return the first element of the queue.
Raise Empty exception if the queue is empty.
"""
if self.is_empty():
raise Empty('Queue is empty')
answer = self._data[self._front]
self._data[self._front] = None
self._front = (self._front+1) % len(self._data)
self._size -= 1
return answer
def enqueue(self,e):
"""Add an element to the back of the queue."""
if self._size == len(self._data):
self._resize(2*len(self._data)) #double the array size
avail = (self._front + self._size)%len(self._data)
self._data[avail] = e
self._size += 1
def _resize(self,cap):
"""Resize to a new list of capacity >= len(self)."""
old = self._data
self._data = [None]*cap
walk = self._front
for k in range(self._size): #only consider existing elements
self._data[k] = old[walk] #intentionally shift indices
walk = (1+walk)%len(old)
self._front = 0
参考书籍:
Data Structures and Algorithms in Python,WILEY