Python數據結構——隊列(1)

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章