队列(queue)这一数据结构非常适合那些数据按照其被接收的顺序处理的问题。如共享打印机。队列可以被看做一个先进先出的(FIFO)list.
下图为一个队列结构
有多种方式来实现一个队列:list,linked list,array都可以。首先看一个list实现的队列
1、用python list实现队列
class Queue :
# Creates an empty queue.
def __init__( self ):
self._qList = list()
# Returns True if the queue is empty.
def isEmpty( self ):
return len( self ) == 0
# Returns the number of items in the queue.
def __len__( self ):
return len( self._qList )
# Adds the given item to the queue.
def enqueue( self, item ):
self._qList.append( item )
# Removes and returns the first item in the queue.
def dequeue( self ):
assert not self.isEmpty(), "Cannot dequeue from an empty queue."
return self._qList.pop( 0 )
下面是队列的使用和控制台输出:
myQueue = Queue()
myQueue.enqueue("apple")
myQueue.enqueue("1000")
myQueue.enqueue("机器")
print(len(myQueue))
myQueue.dequeue()
print(myQueue.isEmpty())
使用list实现的队列在入队和出队时由于可能移动元素,最糟糕的情况下所需的时间复杂度为O(n).
我们可以用另一种数据结构–环形数组(circular Array)来改善这种情况。环形数组仍然是一个数组,只不过被视作一个圆环而不是一条线。如图:
环形数组可以允许我们添加或删除现有数据的情况下不必按顺序移动元素。但环形数据有一个最大容量(maximum-capacity),所以环形数组适合处理数据量不大的问题。
2、用环形数组实现队列(引用的Array在本文最后)
from myArray import Array
class Queue2 :
# Creates an empty queue.
def __init__( self, maxSize ) :
self._count = 0
self._front = 0
self._back = maxSize - 1
self._qArray = Array( maxSize )
# Returns True if the queue is empty.
def isEmpty( self ) :
return self._count == 0
# Returns True if the queue is full.
def isFull( self ) :
return self._count == len(self._qArray)
# Returns the number of items in the queue.
def __len__( self ) :
return self._count
# Adds the given item to the queue.
def enqueue( self, item ):
assert not self.isFull(), "Cannot enqueue to a full queue."
maxSize = len(self._qArray)
self._back = (self._back + 1) % maxSize
self._qArray[self._back] = item
self._count += 1
# Removes and returns the first item in the queue.
def dequeue( self ):
assert not self.isEmpty(), "Cannot dequeue from an empty queue."
item = self._qArray[ self._front ]
maxSize = len(self._qArray)
self._front = (self._front + 1) % maxSize
self._count -= 1
return item
下面是队列的使用和控制台输出
aqueue = Queue2(10)
aqueue.enqueue("orange")
aqueue.enqueue("300")
print("aqueue的长度:%d" %len(aqueue))
aqueue.dequeue()
print("aqueue的长度:%d" %len(aqueue))
使用python list实现的队列最大的不足是入队和出队时的时间开销,用环形数组虽然解决了这个不足,但环形数组容量有大小限制。一个更好的解决方法是使用链表,如图
class Queue3:
def __init__(self):
self._qhead = None
self._qtail = None
self._count = 0
def __len__(self):
return self._count
def isEmpty(self):
return self._qhead is None
def enqueue(self,item):
node = _QueueNode(item)
if self.isEmpty():
self._qhead = node
else:
self._qtail.next = node #新的节点链到tail的next
self._qtail = node #新的节点成为新tail
self._count += 1
def dequeue(self):
assert not self.isEmpty(), "buneng"
node = self._qhead
if self._qhead is self._qtail:
self._qtail = None
else:
self._qhead = self._qhead.next
self._count -= 1
return node.item
class _QueueNode(object):
def __init__(self, item):
self.item = item
self.next = None
队列的使用和控制台输出
anoqueue = Queue3()
anoqueue.enqueue("banana")
anoqueue.enqueue("咖啡")
print("anoqueue长度是%d" %len(anoqueue))
print(anoqueue.dequeue())
myArray.py
import ctypes
class Array :
# Creates an array with size elements.
def __init__( self, size ):
assert size > 0, "Array size must be > 0"
self._size = size
# Create the array structure using the ctypes module.
PyArrayType = ctypes.py_object * size
self._elements = PyArrayType()
# Initialize each element.
self.clear( None )
# Returns the size of the array.
def __len__( self ):
return self._size
# Gets the contents of the index element.
def __getitem__( self, index ):
assert index >= 0 and index < len(self), "Array subscript out of range"
return self._elements[ index ]
# Puts the value in the array element at index position.
def __setitem__( self, index, value ):
assert index >= 0 and index < len(self), "Array subscript out of range"
self._elements[ index ] = value
# Clears the array by setting each element to the given value.
def clear( self, value ):
for i in range( len(self) ) :
self._elements[i] = value
# Returns the array's iterator for traversing the elements.
def __iter__( self ):
return _ArrayIterator( self._elements )
# An iterator for the Array ADT.
class _ArrayIterator :
def __init__( self, theArray ):
self._arrayRef = theArray
self._curNdx = 0
def __iter__( self ):
return self
def __next__( self ):
if self._curNdx < len( self._arrayRef ) :
entry = self._arrayRef[ self._curNdx ]
self._curNdx += 1
return entry
else :
raise StopIteration
据 Data Structures and Algorithms Using Python一书整理