[Python数据结构] 使用 Circular List实现Queue
[Python数据结构] 使用 Circular List实现Queue
1. Queue
队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端进行删除操作。队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。
2. Queue ADT
队列是一种抽象数据类型,其实例Q需要支持两种方法:
1)Q.enqueue(e) : Add an element to the back of queue.
2)Q.dequeue( ) : Remove and return the first element in the queue
另外,为了方便使用,我们还定义了以下方法:
3)Q.first() : Return the element at the front of the queue
4)Q.is_empty() : Return True if the queue is empty
5)len(Q) : Return the number of elements in the queue
3. Queue Implementation
1 class Empty(Exception): 2 """Error attempting to access an element from an empty container""" 3 pass
1 class ArrayQueue(): 2 """FIFO queue implementation using a python list as underlying storage.""" 3 Default_capacity = 10 4 5 def __init__(self): 6 """Create an empty queue""" 7 self.data = [None] * ArrayQueue.Default_capacity # reference to a list instance with a fixed capacity. 8 self.size = 0 # an integer representing the current number of elements stored in the queue. 9 self.front = 0 # an integer that represents the index within data of the first element of the queue. 10 11 def __len__(self): 12 """Return the number od elements in the queue.""" 13 return self.size 14 15 def is_empty(self): 16 """Return True if the queue is empty.""" 17 return self.size == 0 18 19 def first(self): 20 """Return the element at the front of the queue. 21 22 Raise Empty exception if the queue is empty.""" 23 if self.is_empty(): 24 raise Empty('the queue is empty') 25 return self.data[self.front] 26 27 def dequeue(self): 28 """Remove and return the first element in the queue. 29 30 Raise Empty exception if the queue is empty.""" 31 if self.is_empty(): 32 raise Empty('the queue is empty') 33 answer = self.data[self.front] 34 self.data[self.front] = None 35 self.front = (self.front + 1) % len(self.data) 36 self.size -= 1 37 return answer 38 39 def enqueue(self, e): 40 """Add an element to the back of queue.""" 41 if self.size == len(self.data): 42 self.resize(2 * len(self.data)) 43 avail = (self.front + self.size) % len(self.data) 44 self.data[avail] = e 45 self.size += 1 46 47 def resize(self, cap): 48 """Resize to a new list of capacity.""" 49 old = self.data 50 self.data = [None] * cap 51 walk = self.front 52 for k in range(self.size): 53 self.data[k] = old[walk] 54 walk = (1 + walk) % len(old) 55 self.front = 0
4. 执行结果:
1 q = ArrayQueue() 2 l = np.random.randint(0, 10, size=(20, )) 3 for i in l: 4 q.enqueue(i)
1 q.data 2 [0, 1, 5, 3, 9, 5, 0, 9, 1, 0, 4, 6, 7, 0, 2, 5, 9, 3, 3, 9]
1 q.dequeue() 2 0
1 q.data 2 [None, 1, 5, 3, 9, 5, 0, 9, 1, 0, 4, 6, 7, 0, 2, 5, 9, 3, 3, 9]
1 q.first() 2 1
1 q.data 2 [None, 1, 5, 3, 9, 5, 0, 9, 1, 0, 4, 6, 7, 0, 2, 5, 9, 3, 3, 9]