[Python data structure] using Circular List to implement Queue

Keywords: Python

[Python data structure] using Circular List to implement Queue


1. Queue

Queues, also known as queue s, are first in first out linear tables. In practical application, it is usually realized by linked list or array. Queues can only be inserted at the back end (called rear) and deleted at the front end.

The operation of queues is similar to that of stacks. The only difference is that queues only allow new data to be added at the back end.

See here for Queue information

2. Queue ADT

Queue is an abstract data type. In fact, example Q needs to support two methods:
1)Q.enqueue(e)  : Add an element to the back of queue. 2)Q.dequeue( )  : Remove and return the first element in the queue

In addition, for ease of use, we also define the following methods:
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

class Empty(Exception):
    """Error attempting to access an element from an empty container"""
    pass
class ArrayQueue():
    """FIFO queue implementation using a python list as underlying storage."""
    Default_capacity = 10
    
    def __init__(self):
        """Create an empty queue"""
        self.data = [None] * ArrayQueue.Default_capacity  # reference to a list instance with a fixed capacity.
        self.size = 0  # an integer representing the current number of elements stored in the queue.
        self.front = 0  # an integer that represents the index within data of the first element of the queue.
        
    def __len__(self):
        """Return the number od elements in the queue."""
        return self.size
    
    def is_empty(self):
        """Return True if the queue is empty."""
        return self.size == 0
    
    def first(self):
        """Return the element at the front of the queue.
        
        Raise Empty exception if the queue is empty."""
        if self.is_empty():
            raise Empty('the queue is empty')
        return self.data[self.front]
           
    def dequeue(self):
        """Remove and return the first element in the queue.
        
        Raise Empty exception if the queue is empty."""
        if self.is_empty():
            raise Empty('the queue is empty')
        answer = self.data[self.front]
        self.data[self.front] = None
        self.front = (self.front + 1) % len(self.data)
        self.size -= 1
        return answer
        
    def enqueue(self, e):
        """Add an element to the back of queue."""
        if self.size == len(self.data):
            self.resize(2 * len(self.data))
        avail = (self.front + self.size) % len(self.data)
        self.data[avail] = e
        self.size += 1  
        
    def resize(self, cap):
        """Resize to a new list of capacity."""
        old = self.data
        self.data = [None] * cap
        walk = self.front
        for k in range(self.size):
            self.data[k] = old[walk]
            walk = (1 + walk) % len(old)
        self.front = 0
Execution result:

q = ArrayQueue()
l = np.random.randint(0, 10, size=(20, ))
for i in l:
    q.enqueue(i)
q.data
[0, 1, 5, 3, 9, 5, 0, 9, 1, 0, 4, 6, 7, 0, 2, 5, 9, 3, 3, 9]
q.dequeue()
0
q.data
[None, 1, 5, 3, 9, 5, 0, 9, 1, 0, 4, 6, 7, 0, 2, 5, 9, 3, 3, 9]
q.first()
1
q.data
[None, 1, 5, 3, 9, 5, 0, 9, 1, 0, 4, 6, 7, 0, 2, 5, 9, 3, 3, 9]

Posted by Gomesh on Sat, 02 May 2020 15:47:59 -0700