隊列(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一書整理