Skip to content

Commit 6fc2fd9

Browse files
committed
refactor: Enhance docs, add tests in GenericHeap
1 parent 5246f63 commit 6fc2fd9

File tree

2 files changed

+169
-8
lines changed

2 files changed

+169
-8
lines changed

src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,86 @@
33
import java.util.ArrayList;
44
import java.util.HashMap;
55

6+
/**
7+
* A generic implementation of a max heap data structure.
8+
*
9+
* @param <T> the type of elements in this heap, must extend Comparable.
10+
*/
611
public class GenericHeap<T extends Comparable<T>> {
712

8-
ArrayList<T> data = new ArrayList<>();
9-
HashMap<T, Integer> map = new HashMap<>();
13+
private final ArrayList<T> data = new ArrayList<>();
14+
private final HashMap<T, Integer> map = new HashMap<>();
1015

16+
/**
17+
* Adds an item to the heap, maintaining the heap property.
18+
*
19+
* @param item the item to be added
20+
*/
1121
public void add(T item) {
1222
this.data.add(item);
13-
map.put(item, this.data.size() - 1); //
23+
map.put(item, this.data.size() - 1);
1424
upHeapify(this.data.size() - 1);
1525
}
1626

27+
/**
28+
* Restores the heap property by moving the item at the given index upwards.
29+
*
30+
* @param ci the index of the current item
31+
*/
1732
private void upHeapify(int ci) {
1833
int pi = (ci - 1) / 2;
19-
if (isLarger(this.data.get(ci), this.data.get(pi)) > 0) {
34+
if (ci > 0 && isLarger(this.data.get(ci), this.data.get(pi)) > 0) {
2035
swap(pi, ci);
2136
upHeapify(pi);
2237
}
2338
}
2439

40+
/**
41+
* Displays the contents of the heap.
42+
*/
2543
public void display() {
2644
System.out.println(this.data);
2745
}
2846

47+
/**
48+
* Returns the number of elements in the heap.
49+
*
50+
* @return the size of the heap
51+
*/
2952
public int size() {
3053
return this.data.size();
3154
}
3255

56+
/**
57+
* Checks if the heap is empty.
58+
*
59+
* @return true if the heap is empty, false otherwise
60+
*/
3361
public boolean isEmpty() {
3462
return this.size() == 0;
3563
}
3664

65+
/**
66+
* Removes and returns the maximum item from the heap.
67+
*
68+
* @return the maximum item
69+
*/
3770
public T remove() {
71+
if (isEmpty()) {
72+
throw new IllegalStateException("Heap is empty");
73+
}
3874
this.swap(0, this.size() - 1);
3975
T rv = this.data.remove(this.size() - 1);
40-
downHeapify(0);
4176
map.remove(rv);
77+
downHeapify(0);
4278
return rv;
4379
}
4480

81+
/**
82+
* Restores the heap property by moving the item at the given index downwards.
83+
*
84+
* @param pi the index of the current item
85+
*/
4586
private void downHeapify(int pi) {
4687
int lci = 2 * pi + 1;
4788
int rci = 2 * pi + 2;
@@ -58,15 +99,35 @@ private void downHeapify(int pi) {
5899
}
59100
}
60101

102+
/**
103+
* Retrieves the maximum item from the heap without removing it.
104+
*
105+
* @return the maximum item
106+
*/
61107
public T get() {
62-
return this.data.get(0);
108+
if (isEmpty()) {
109+
throw new IllegalStateException("Heap is empty");
110+
}
111+
return this.data.getFirst();
63112
}
64113

65-
// t has higher property then return +ve
114+
/**
115+
* Compares two items to determine their order.
116+
*
117+
* @param t the first item
118+
* @param o the second item
119+
* @return a positive integer if t is greater than o, negative if t is less, and zero if they are equal
120+
*/
66121
private int isLarger(T t, T o) {
67122
return t.compareTo(o);
68123
}
69124

125+
/**
126+
* Swaps two items in the heap and updates their indices in the map.
127+
*
128+
* @param i index of the first item
129+
* @param j index of the second item
130+
*/
70131
private void swap(int i, int j) {
71132
T ith = this.data.get(i);
72133
T jth = this.data.get(j);
@@ -76,9 +137,16 @@ private void swap(int i, int j) {
76137
map.put(jth, i);
77138
}
78139

140+
/**
141+
* Updates the priority of the specified item by restoring the heap property.
142+
*
143+
* @param item the item whose priority is to be updated
144+
*/
79145
public void updatePriority(T item) {
146+
if (!map.containsKey(item)) {
147+
throw new IllegalArgumentException("Item not found in the heap");
148+
}
80149
int index = map.get(item);
81-
// because we enter lesser value then old vale
82150
upHeapify(index);
83151
}
84152
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package com.thealgorithms.datastructures.heaps;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
import static org.junit.jupiter.api.Assertions.assertTrue;
7+
8+
import org.junit.jupiter.api.BeforeEach;
9+
import org.junit.jupiter.api.Test;
10+
11+
class GenericHeapTest {
12+
13+
private GenericHeap<Integer> heap;
14+
15+
@BeforeEach
16+
void setUp() {
17+
heap = new GenericHeap<>();
18+
}
19+
20+
@Test
21+
void testAddAndGet() {
22+
heap.add(10);
23+
heap.add(20);
24+
heap.add(5);
25+
26+
assertEquals(20, heap.get());
27+
}
28+
29+
@Test
30+
void testRemove() {
31+
heap.add(10);
32+
heap.add(20);
33+
heap.add(5);
34+
35+
assertEquals(20, heap.remove());
36+
assertEquals(10, heap.get());
37+
}
38+
39+
@Test
40+
void testIsEmpty() {
41+
assertTrue(heap.isEmpty());
42+
heap.add(1);
43+
assertFalse(heap.isEmpty());
44+
}
45+
46+
@Test
47+
void testSize() {
48+
assertEquals(0, heap.size());
49+
heap.add(1);
50+
heap.add(2);
51+
assertEquals(2, heap.size());
52+
}
53+
54+
@Test
55+
void testUpdatePriority() {
56+
heap.add(10);
57+
heap.add(20);
58+
heap.add(5);
59+
60+
heap.updatePriority(10); // This is a no-op since 10 is not greater than 20.
61+
assertEquals(20, heap.get());
62+
63+
heap.add(30);
64+
heap.updatePriority(20); // 20 will be moved up
65+
assertEquals(30, heap.get());
66+
}
67+
68+
@Test
69+
void testRemoveFromEmptyHeap() {
70+
Exception exception = assertThrows(IllegalStateException.class, () -> heap.remove());
71+
assertEquals("Heap is empty", exception.getMessage());
72+
}
73+
74+
@Test
75+
void testGetFromEmptyHeap() {
76+
Exception exception = assertThrows(IllegalStateException.class, () -> heap.get());
77+
assertEquals("Heap is empty", exception.getMessage());
78+
}
79+
80+
@Test
81+
void testUpdatePriorityForNonExistentItem() {
82+
Exception exception = assertThrows(IllegalArgumentException.class, () -> heap.updatePriority(100));
83+
assertEquals("Item not found in the heap", exception.getMessage());
84+
}
85+
86+
@Test
87+
void testDisplay() {
88+
heap.add(10);
89+
heap.add(20);
90+
heap.add(5);
91+
heap.display(); // Just checking no exceptions are thrown.
92+
}
93+
}

0 commit comments

Comments
 (0)