Queue - Tomekske/algorithms GitHub Wiki

Queue

A queue is a data structure that follows the First-In-First-Out (FIFO) principle. It works like a line or queue in real life, where the first person to join is the first to be served. Elements are added to the back and removed from the front, preserving their original order. Queues are commonly used when the order of processing is important, like in task scheduling or job processing.

Usage

  • Task Scheduling: Used to manage and schedule tasks or jobs in systems where multiple tasks need to be executed in a specific order. The tasks are added to the queue, and they are processed one by one in the order they were added.
  • Message Queues: In distributed systems or message-oriented architectures, message queues provide a reliable way to handle asynchronous communication between components. Messages are placed in a queue and processed by different components at their own pace.
  • Breadth-First Search: Queue data structure is essential in graph algorithms like breadth-first search (BFS), which explores a graph level by level. In BFS, the nodes are visited in the order they were discovered, and a queue is used to manage the nodes that need to be visited.
  • Resource Sharing: Queues are used to manage shared resources, such as printers, processors, or network connections, where multiple processes or threads need to access the resource in a controlled and ordered manner.
  • Web Servers and Load Balancing: In web servers and load balancing systems, queues are used to manage incoming requests. The requests are placed in a queue and processed by available resources or servers to balance the load and ensure fair request handling.
  • Event-driven Programming: In event-driven programming, queues are often used to handle events or callbacks asynchronously. Events are added to a queue and processed in the order they occurred, allowing for efficient event handling and decoupling of components.

Operations

Main operations

  • Enqueue: Adds an element to the top of the queue
  • Dequeue: Removes the top element from the queue

Additional operations

  • Peek: Access the top element of the queue without removing it
  • Size: Returns the number of elements in the queue
  • Clear: Removes all elements from the queue

Push Operation

Pseudo Code

class
    private queue: array
    
    procedure enqueue(item)
        queue.add(item)
    end procedure
end class

Complexity

  • Time: $O(1)$
  • Space: $O(1)$

Pop Operation

Pseudo Code

class
    private queue: array
    
    procedure dequeue()
        if queue is empty then
            return null
        else
            return remove queue[head]
        end if
    end procedure
end class

Complexity

  • Time: $O(1)$
  • Space: $O(1)$

Peek Operation

Pseudo Code

class
    private queue: array
    
    procedure peek()
        if queue is empty then
            return null
        else
            return queue[top]
        end if
    end procedure
end class

Complexity

  • Time: $O(1)$
  • Space: $O(1)$

Size Operation

Pseudo Code

class
    private queue: array
    
    procedure size()
        return queue.length()
    end procedure
end class

Complexity

  • Time: $O(1)$
  • Space: $O(1)$

Clear Operation

Pseudo Code

class
    private queue: array
    
    function clear():
        while queue is not empty do:
            pop an element from the queue
        end while
    end function
end class

Complexity

  • Time: $O(n)$
  • Space: $O(1)$

Pros and Cons

Pros:

  • First-In-First-Out (FIFO): The primary advantage of a queue is its FIFO behavior, where the element that is added first will be the first one to be removed
  • Simple and Easy to Implement: Queues have a straightforward implementation using arrays or linked lists Efficient Insertion and Removal: This efficiency makes queues efficient for managing large datasets or handling real-time data streams.
  • Synchronization and Coordination: Queues can be used for synchronization and coordination between different parts of a program or multiple threads. They provide a reliable and orderly way to pass data or tasks between different components.

Cons:

  • Lack of Random Access: You can only access the front or rear element in a queue
  • Inefficient Search: Queues are not designed for efficient search operations. To find an element within a queue, you would need to dequeue elements until you reach the desired element
  • Fixed Capacity: In some implementations, queues may have a fixed capacity, meaning they can only hold a certain number of elements
  • Memory Overhead: Depending on the implementation, queues can have some memory overhead. For example, linked list-based queues require extra memory to store the references or pointers to the next nodes. If memory usage is a critical concern, it's essential to consider the trade-offs between different implementations.