Improve priority queues with max-heap (#3648)

This commit is contained in:
PuneetTri 2022-12-13 23:32:15 +05:30 committed by GitHub
parent 8ba295b1ad
commit 5512fea0a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,5 +1,8 @@
package com.thealgorithms.datastructures.queues;
/**
* This class implements a PriorityQueue.
*
@ -8,6 +11,8 @@ package com.thealgorithms.datastructures.queues;
* most important elements are placed at the front/on the top. In this example I
* give numbers that are bigger, a higher priority. Queues in theory have no
* fixed size but when using an array implementation it does.
* <p>
* Additional contibutions made by: PuneetTri(https://github.com/PuneetTri)
*/
class PriorityQueue {
@ -25,42 +30,113 @@ class PriorityQueue {
private int nItems;
/**
* Constructor
* Default Constructor
*/
public PriorityQueue() {
/* If capacity is not defined, default size of 11 would be used
* capacity=max+1 because we cant access 0th element of PQ, and to
* accomodate (max)th elements we need capacity to be max+1.
* Parent is at position k, child at position (k*2,k*2+1), if we
* use position 0 in our queue, its child would be at:
* (0*2, 0*2+1) -> (0,0). This is why we start at position 1
*/
int size = 11; // Default value of 11
maxSize = size + 1;
queueArray = new int[maxSize];
nItems = 0;
}
/**
* Parameterized Constructor
*
* @param size Size of the queue
*/
public PriorityQueue(int size) {
maxSize = size;
queueArray = new int[size];
maxSize = size + 1;
queueArray = new int[maxSize];
nItems = 0;
}
/**
* Helper function for the max-heap implementation of PQ
* Function would help demote parent node to their correct
* position
*
* @param pos Position of newly added element at bottom
*/
private void swim(int pos) {
// Check if parent is smaller than child node
while (pos > 1 && (queueArray[pos / 2] < queueArray[pos])) {
// In such case swap value of child with parent
int temp = queueArray[pos];
queueArray[pos] = queueArray[pos / 2];
queueArray[pos / 2] = temp;
pos = pos / 2; // Jump to position of parent node
}
// Promotion of child node will go on until it becomes smaller than the parent
}
/**
* Helper function for the max-heap implementation of PQ
* Function would help demote parent node to their correct
* position
*
* @param pos Position of element at top
*/
private void sink(int pos) {
// Check if node's position is that of parent node
while (2 * pos <= nItems) {
int current = 2 * pos; // Jump to the positon of child node
// Compare both the children for the greater one
if (current < nItems && queueArray[current] < queueArray[current + 1]) current++;
// If the parent node is greater, sink operation is complete. Break the loop
if (queueArray[pos] >= queueArray[current]) break;
// If not exchange the value of parent with child
int temp = queueArray[pos];
queueArray[pos] = queueArray[current];
queueArray[current] = temp;
pos = current; // Exchange parent position to child position in the array
}
}
/**
* Inserts an element in it's appropriate place
*
* @param value Value to be inserted
*/
public void insert(int value) {
// Print overflow message if the capacity is full
if (isFull()) {
throw new RuntimeException("Queue is full");
} else {
int j = nItems - 1; // index of last element
while (j >= 0 && queueArray[j] > value) {
queueArray[j + 1] = queueArray[j]; // Shifts every element up to make room for insertion
j--;
}
queueArray[j + 1] = value; // Once the correct position is found the value is inserted
nItems++;
queueArray[++nItems] = value;
swim(nItems); // Swim up the element to its correct position
}
}
/**
* Remove the element from the front of the queue
* Dequeue the element with the max priority from PQ
*
* @return The element removed
*/
public int remove() {
return queueArray[--nItems];
if (isEmpty()) {
throw new RuntimeException("Queue is Empty");
} else {
int max = queueArray[1]; // By defintion of our max-heap, value at queueArray[1] pos is the greatest
// Swap max and last element
int temp = queueArray[1];
queueArray[1] = queueArray[nItems];
queueArray[nItems] = temp;
queueArray[nItems--] = 0; // Nullify the last element from the priority queue
sink(1); // Sink the element in order
return max;
}
}
/**
@ -69,7 +145,7 @@ class PriorityQueue {
* @return element at the front of the queue
*/
public int peek() {
return queueArray[nItems - 1];
return queueArray[1];
}
/**
@ -87,7 +163,7 @@ class PriorityQueue {
* @return true if the queue is full
*/
public boolean isFull() {
return (nItems == maxSize);
return (nItems == maxSize - 1);
}
/**
@ -100,29 +176,3 @@ class PriorityQueue {
}
}
/**
* This class implements the PriorityQueue class above.
*
* @author Unknown
*/
public class PriorityQueues {
/**
* Main method
*
* @param args Command Line Arguments
*/
public static void main(String[] args) {
PriorityQueue myQueue = new PriorityQueue(4);
myQueue.insert(10);
myQueue.insert(2);
myQueue.insert(5);
myQueue.insert(3);
// [2, 3, 5, 10] Here higher numbers have higher priority, so they are on the top
for (int i = 3; i >= 0; i--) {
System.out.print(myQueue.remove() + " "); // will print the queue in reverse order [10, 5, 3, 2]
}
// As you can see, a Priority Queue can be used as a sorting algotithm
}
}