Double Ended Priority Queue

Introduction to the double-ended priority queue

A double-ended priority queue (DEPQ) is a data structure that stores a collection of elements, where each element is associated with a priority or value. Elements can be inserted and removed from both ends of the queue based on their priority.

The highest priority element can be accessed from either end of the queue without removing it. In a DEPQ, the elements are stored in a way that maintains their priority order, such that the highest priority element is always at the front or back of the queue, depending on the implementation.

Basic Terms:

Priority Queue - A priority queue is a collection of items where each item has a priority assigned to it, and the items are handled in priority order.

Double-Ended Queue - A double-ende queue is a collection of items that permits insertion and deletion from both the front and the back of the queue

Properties of DEPQ

  • A DEPQ permits actions like inserting and deleting items with priorities at both ends of the queue.
  • In spite of where they are in the queue, the elements with higher priorities are always processed first.
  • The DEPQ is a valuable data structure for scheduling, task management, and resource allocation applications because of this.
  • Several data structures, including binary heaps, Fibonacci heaps, and balanced binary search trees, can be used to build DEPQs.
  • The needs of the particular application and the trade-offs between time and space complexity determine the best data structure to use.

Operations supported by DEPQs

The following operations are performed on a double-ended priority queue (DEPQ):

  • getMin(): This function returns the minimum element.
  • getMax(): This function returns the maximum element
  • put(x): This function inserts the element 'x' into the DEPQ.
  • removeMin(): As the name indicates, it removes the minimum element from DEPQ
  • removeMax(): It removes the maximum element from the DEPQ.

Self-balancing BST implementation of a DEPQ

A self-balancing BST implementation of a DEPQ provides effective time complexity for all of its operations, and its space complexity is comparable to that of other implementations. Self-balancing trees automatically retain their balanced structure, ensuring quick and reliable performance while working with big data sets.

In C++, a self-balancing binary search tree, such as red-black or AVL trees, is commonly used to implement the set container. These data structures offer set operations with effective worst-case and average-case time complexity.

Output

DEPQ Operations:   
1. Insert an Element
2. Get Minimum Element    
3. Get Maximum Element    
4. Delete Minimum Element 
5. Delete Maximum Element 
6. Size
7. Is Empty?       
0. Exit
Enter your choice: 1
Enter the value to put: 25
Value inserted successfully.
Enter your choice: 1
Enter the value to put: 75
Value inserted successfully.
Enter your choice: 1
Enter the value to put: 30
Value inserted successfully.
Enter your choice: 1
Enter the value to put: 90
Value inserted successfully.
Enter your choice: 1
Enter the value to put: 55
Value inserted successfully.
Enter your choice: 6
DEPQ size: 5
Enter your choice: 7
DEPQ is not empty.
Enter your choice: 2
Minimum value: 25
Enter your choice: 3
Maximum value: 90
Enter your choice: 4
Minimum value deleted successfully.
Enter your choice: 5
Maximum value deleted successfully.
Enter your choice: 2
Minimum value: 30
Enter your choice: 3
Maximum value: 75
Enter your choice: 0
Successfully Exited!

Time Complexity of each function:

put()O(logn)
removeMin()O(logn)
removeMax()O(logn)
getMin()O(1)
getMax()O(1)
size()O(1)
isEmpty()O(1)

Implementation of Double-Ended Priority Queue in Java

In this implementation, we used a TreeSet to store the elements in a sorted manner. The TreeSet allows us to easily retrieve the minimum and maximum elements and also perform insertion and deletion in O(log n) time complexity.

Output

Inserted 25 Successfully!
Inserted 75 Successfully!
Inserted 30 Successfully!
Inserted 90 Successfully!
Inserted 55 Successfully!
Size of the DEPQ : 5
Is empty? : false
Minimum Element : 25
Maximum Element : 90
Maximum Element Deleted Successfully!
New Maxmium Element : 75
Minimum Element Deleted Successfully!
New Minimum Element : 30
Size of the DEPQ now : 3

Implementation of Double-Ended Priority Queue in Python

The bisect module, which supports maintaining a list in sorted order without requiring the list to be sorted after each insertion, is used in this implementation. Using the bisect.insort() function, the element is inserted in the proper spot to preserve the sorted order. This enables us to insert and delete items in operations of O(log n) time complexity and obtain the minimum and the maximum elements in O(1) time.

Output

Inserted 25 Successfully!
Inserted 75 Successfully!
Inserted 30 Successfully!
Inserted 90 Successfully!
Inserted 55 Successfully!
Size of the DEPQ : 5
is Empty? : False
Minimum Element : 25
Maximum Element : 90
Maximum Elemented Deleted Successfully!
Maximum Element : 75
Minimum Elemented Deleted Successfully!
New Minimum Element : 30
Size of the DEPQ now : 3

Comparing Heap implementation vs. BBST implementation of DEPQ

Implementing a Double-Ended Priority Queue (DEPQ) using a Heap vs. a Balanced Binary Search Tree (BBST):

Heap Implementation:

  • A Heap is a complete binary tree that satisfies the heap property.
  • Inserting an element takes O(log n) time, where n is the number of elements in a heap.
  • Deleting the minimum or maximum element takes O(log n) time.
  • Getting the minimum or maximum element takes O(1) time.
  • The space complexity of a heap is O(n).

Balanced Binary Search Tree (BBST) Implementation:

  • A BBST is a binary tree that satisfies the balance property, such as an AVL or Red-Black tree.
  • Inserting an element takes O(log n) time, where n is the number of elements in the tree.
  • Deleting the minimum or maximum element takes O(log n) time.
  • Getting the minimum or maximum element takes O(log n) time.
  • The space complexity of a BBST is O(n).

Comparing these two implementations, we can see that:

  • Heap has a faster time complexity for getting the minimum or maximum element (O(1) vs. O(log n)), but a slower time complexity for inserting and deleting elements (O(log n) vs. O(log n)).
  • BBST has a slower time complexity for getting the minimum or maximum element but a faster time complexity for inserting and deleting elements.
  • The space complexity of both implementations is the same.
  • Therefore, the implementation choice depends on the specific use case and the most frequently performed operations. A heap may be a better choice if getting the minimum or maximum element is a more frequent operation. On the other hand, if inserting and deleting elements are more frequent, then a BBST may be a better choice.





Latest Courses