首页 > 技术文章 > [Python数据结构] 使用 Circular List实现Queue

iwangzhengchao 2018-10-24 18:45 原文

[Python数据结构] 使用 Circular List实现Queue

1. Queue
队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端进行删除操作。队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。

Queue[维基百科]

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]

 

推荐阅读