Skip to content

Commit 7e907be

Browse files
committed
refactor: Enhance docs, add tests in MinPriorityQueue
1 parent 5246f63 commit 7e907be

File tree

2 files changed

+172
-61
lines changed

2 files changed

+172
-61
lines changed
Lines changed: 84 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,49 @@
11
package com.thealgorithms.datastructures.heaps;
22

33
/**
4-
* Minimum Priority Queue It is a part of heap data structure A heap is a
5-
* specific tree based data structure in which all the nodes of tree are in a
6-
* specific order. that is the children are arranged in some respect of their
7-
* parents, can either be greater or less than the parent. This makes it a min
8-
* priority queue or max priority queue.
4+
* A MinPriorityQueue is a specialized data structure that maintains the
5+
* min-heap property, where the smallest element has the highest priority.
96
*
10-
* <p>
7+
* <p>In a min-priority queue, every parent node is less than or equal
8+
* to its child nodes, which ensures that the smallest element can
9+
* always be efficiently retrieved.</p>
1110
*
12-
* <p>
13-
* Functions: insert, delete, peek, isEmpty, print, heapSort, sink
11+
* <p>Functions:</p>
12+
* <ul>
13+
* <li><b>insert(int key)</b>: Inserts a new key into the queue.</li>
14+
* <li><b>delete()</b>: Removes and returns the highest priority value (the minimum).</li>
15+
* <li><b>peek()</b>: Returns the highest priority value without removing it.</li>
16+
* <li><b>isEmpty()</b>: Checks if the queue is empty.</li>
17+
* <li><b>isFull()</b>: Checks if the queue is full.</li>
18+
* <li><b>heapSort()</b>: Sorts the elements in ascending order.</li>
19+
* <li><b>print()</b>: Prints the current elements in the queue.</li>
20+
* </ul>
1421
*/
1522
public class MinPriorityQueue {
1623

1724
private final int[] heap;
1825
private final int capacity;
1926
private int size;
2027

21-
// class the constructor and initializes the capacity
22-
MinPriorityQueue(int c) {
28+
/**
29+
* Initializes a new MinPriorityQueue with a specified capacity.
30+
*
31+
* @param c the maximum number of elements the queue can hold
32+
*/
33+
public MinPriorityQueue(int c) {
2334
this.capacity = c;
2435
this.size = 0;
2536
this.heap = new int[c + 1];
2637
}
2738

28-
// inserts the key at the end and rearranges it
29-
// so that the binary heap is in appropriate order
39+
/**
40+
* Inserts a new key into the min-priority queue.
41+
*
42+
* @param key the value to be inserted
43+
*/
3044
public void insert(int key) {
3145
if (this.isFull()) {
32-
return;
46+
throw new IllegalStateException("MinPriorityQueue is full. Cannot insert new element.");
3347
}
3448
this.heap[this.size + 1] = key;
3549
int k = this.size + 1;
@@ -44,89 +58,98 @@ public void insert(int key) {
4458
this.size++;
4559
}
4660

47-
// returns the highest priority value
61+
/**
62+
* Retrieves the highest priority value (the minimum) without removing it.
63+
*
64+
* @return the minimum value in the queue
65+
* @throws IllegalStateException if the queue is empty
66+
*/
4867
public int peek() {
68+
if (isEmpty()) {
69+
throw new IllegalStateException("MinPriorityQueue is empty. Cannot peek.");
70+
}
4971
return this.heap[1];
5072
}
5173

52-
// returns boolean value whether the heap is empty or not
74+
/**
75+
* Checks whether the queue is empty.
76+
*
77+
* @return true if the queue is empty, false otherwise
78+
*/
5379
public boolean isEmpty() {
54-
return 0 == this.size;
80+
return size == 0;
5581
}
5682

57-
// returns boolean value whether the heap is full or not
83+
/**
84+
* Checks whether the queue is full.
85+
*
86+
* @return true if the queue is full, false otherwise
87+
*/
5888
public boolean isFull() {
59-
return this.size == this.capacity;
89+
return size == capacity;
6090
}
6191

62-
// prints the heap
92+
/**
93+
* Prints the elements of the queue.
94+
*/
6395
public void print() {
64-
for (int i = 1; i <= this.capacity; i++) {
96+
for (int i = 1; i <= this.size; i++) {
6597
System.out.print(this.heap[i] + " ");
6698
}
6799
System.out.println();
68100
}
69101

70-
// heap sorting can be done by performing
71-
// delete function to the number of times of the size of the heap
72-
// it returns reverse sort because it is a min priority queue
102+
/**
103+
* Sorts the elements in the queue using heap sort.
104+
*/
73105
public void heapSort() {
74-
for (int i = 1; i < this.capacity; i++) {
106+
for (int i = 1; i <= this.size; i++) {
75107
this.delete();
76108
}
77109
}
78110

79-
// this function reorders the heap after every delete function
111+
/**
112+
* Reorders the heap after a deletion to maintain the heap property.
113+
*/
80114
private void sink() {
81115
int k = 1;
82-
while (2 * k <= this.size || 2 * k + 1 <= this.size) {
83-
int minIndex;
84-
if (this.heap[2 * k] >= this.heap[k]) {
85-
if (2 * k + 1 <= this.size && this.heap[2 * k + 1] >= this.heap[k]) {
86-
break;
87-
} else if (2 * k + 1 > this.size) {
88-
break;
89-
}
116+
while (2 * k <= this.size) {
117+
int minIndex = k; // Assume current index is the minimum
118+
119+
if (2 * k <= this.size && this.heap[2 * k] < this.heap[minIndex]) {
120+
minIndex = 2 * k; // Left child is smaller
90121
}
91-
if (2 * k + 1 > this.size) {
92-
minIndex = this.heap[2 * k] < this.heap[k] ? 2 * k : k;
93-
} else {
94-
if (this.heap[k] > this.heap[2 * k] || this.heap[k] > this.heap[2 * k + 1]) {
95-
minIndex = this.heap[2 * k] < this.heap[2 * k + 1] ? 2 * k : 2 * k + 1;
96-
} else {
97-
minIndex = k;
98-
}
122+
if (2 * k + 1 <= this.size && this.heap[2 * k + 1] < this.heap[minIndex]) {
123+
minIndex = 2 * k + 1; // Right child is smaller
99124
}
125+
126+
if (minIndex == k) {
127+
break; // No swap needed, heap property is satisfied
128+
}
129+
130+
// Swap with the smallest child
100131
int temp = this.heap[k];
101132
this.heap[k] = this.heap[minIndex];
102133
this.heap[minIndex] = temp;
103-
k = minIndex;
134+
135+
k = minIndex; // Move down to the smallest child
104136
}
105137
}
106138

107-
// deletes the highest priority value from the heap
139+
/**
140+
* Deletes and returns the highest priority value (the minimum) from the queue.
141+
*
142+
* @return the minimum value from the queue
143+
* @throws IllegalStateException if the queue is empty
144+
*/
108145
public int delete() {
146+
if (isEmpty()) {
147+
throw new IllegalStateException("MinPriorityQueue is empty. Cannot delete.");
148+
}
109149
int min = this.heap[1];
110-
this.heap[1] = this.heap[this.size];
111-
this.heap[this.size] = min;
150+
this.heap[1] = this.heap[this.size]; // Move last element to the root
112151
this.size--;
113152
this.sink();
114153
return min;
115154
}
116-
117-
public static void main(String[] args) {
118-
// testing
119-
MinPriorityQueue q = new MinPriorityQueue(8);
120-
q.insert(5);
121-
q.insert(2);
122-
q.insert(4);
123-
q.insert(1);
124-
q.insert(7);
125-
q.insert(6);
126-
q.insert(3);
127-
q.insert(8);
128-
q.print(); // [ 1, 2, 3, 5, 7, 6, 4, 8 ]
129-
q.heapSort();
130-
q.print(); // [ 8, 7, 6, 5, 4, 3, 2, 1 ]
131-
}
132155
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.thealgorithms.datastructures.heaps;
2+
3+
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.Test;
5+
6+
public class MinPriorityQueueTest {
7+
8+
@Test
9+
void testInsertAndPeek() {
10+
MinPriorityQueue queue = new MinPriorityQueue(5);
11+
queue.insert(10);
12+
queue.insert(5);
13+
queue.insert(15);
14+
15+
Assertions.assertEquals(5, queue.peek(), "The minimum element should be 5.");
16+
}
17+
18+
@Test
19+
void testDelete() {
20+
MinPriorityQueue queue = new MinPriorityQueue(5);
21+
queue.insert(10);
22+
queue.insert(5);
23+
queue.insert(15);
24+
25+
Assertions.assertEquals(5, queue.delete(), "The deleted minimum element should be 5.");
26+
Assertions.assertEquals(10, queue.peek(), "After deletion, the new minimum should be 10.");
27+
}
28+
29+
@Test
30+
void testIsEmpty() {
31+
MinPriorityQueue queue = new MinPriorityQueue(5);
32+
Assertions.assertTrue(queue.isEmpty(), "The queue should be empty initially.");
33+
34+
queue.insert(10);
35+
Assertions.assertFalse(queue.isEmpty(), "The queue should not be empty after insertion.");
36+
}
37+
38+
@Test
39+
void testIsFull() {
40+
MinPriorityQueue queue = new MinPriorityQueue(2);
41+
queue.insert(10);
42+
queue.insert(5);
43+
44+
Assertions.assertTrue(queue.isFull(), "The queue should be full after inserting two elements.");
45+
queue.delete();
46+
Assertions.assertFalse(queue.isFull(), "The queue should not be full after deletion.");
47+
}
48+
49+
@Test
50+
void testHeapSort() {
51+
MinPriorityQueue queue = new MinPriorityQueue(5);
52+
queue.insert(10);
53+
queue.insert(5);
54+
queue.insert(15);
55+
queue.insert(1);
56+
queue.insert(3);
57+
58+
// Delete all elements to sort the queue
59+
int[] sortedArray = new int[5];
60+
for (int i = 0; i < 5; i++) {
61+
sortedArray[i] = queue.delete();
62+
}
63+
64+
// Validate the sorted order
65+
Assertions.assertArrayEquals(new int[] {1, 3, 5, 10, 15}, sortedArray, "The array should be sorted in ascending order.");
66+
}
67+
68+
@Test
69+
void testPeekEmptyQueue() {
70+
MinPriorityQueue queue = new MinPriorityQueue(5);
71+
Assertions.assertThrows(IllegalStateException.class, queue::peek, "Should throw an exception when peeking into an empty queue.");
72+
}
73+
74+
@Test
75+
void testDeleteEmptyQueue() {
76+
MinPriorityQueue queue = new MinPriorityQueue(5);
77+
Assertions.assertThrows(IllegalStateException.class, queue::delete, "Should throw an exception when deleting from an empty queue.");
78+
}
79+
80+
@Test
81+
void testInsertWhenFull() {
82+
MinPriorityQueue queue = new MinPriorityQueue(2);
83+
queue.insert(10);
84+
queue.insert(5);
85+
86+
Assertions.assertThrows(IllegalStateException.class, () -> queue.insert(15), "Should throw an exception when inserting into a full queue.");
87+
}
88+
}

0 commit comments

Comments
 (0)