Skip to content

Commit 94fb92e

Browse files
authored
Enhance docs, add tests in GenericHeap (#5980)
1 parent 63d13b6 commit 94fb92e

File tree

2 files changed

+112
-92
lines changed

2 files changed

+112
-92
lines changed

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

+73-12
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,83 @@
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
if (item == null) {
1323
throw new IllegalArgumentException("Cannot insert null into the heap.");
1424
}
1525

1626
this.data.add(item);
17-
map.put(item, this.data.size() - 1); //
27+
map.put(item, this.data.size() - 1);
1828
upHeapify(this.data.size() - 1);
1929
}
2030

31+
/**
32+
* Restores the heap property by moving the item at the given index upwards.
33+
*
34+
* @param ci the index of the current item
35+
*/
2136
private void upHeapify(int ci) {
2237
int pi = (ci - 1) / 2;
23-
if (isLarger(this.data.get(ci), this.data.get(pi)) > 0) {
38+
if (ci > 0 && isLarger(this.data.get(ci), this.data.get(pi)) > 0) {
2439
swap(pi, ci);
2540
upHeapify(pi);
2641
}
2742
}
2843

29-
public void display() {
30-
System.out.println(this.data);
31-
}
32-
44+
/**
45+
* Returns the number of elements in the heap.
46+
*
47+
* @return the size of the heap
48+
*/
3349
public int size() {
3450
return this.data.size();
3551
}
3652

53+
/**
54+
* Checks if the heap is empty.
55+
*
56+
* @return true if the heap is empty, false otherwise
57+
*/
3758
public boolean isEmpty() {
3859
return this.size() == 0;
3960
}
4061

62+
/**
63+
* Removes and returns the maximum item from the heap.
64+
*
65+
* @return the maximum item
66+
*/
4167
public T remove() {
68+
if (isEmpty()) {
69+
throw new IllegalStateException("Heap is empty");
70+
}
4271
this.swap(0, this.size() - 1);
4372
T rv = this.data.remove(this.size() - 1);
44-
downHeapify(0);
4573
map.remove(rv);
74+
downHeapify(0);
4675
return rv;
4776
}
4877

78+
/**
79+
* Restores the heap property by moving the item at the given index downwards.
80+
*
81+
* @param pi the index of the current item
82+
*/
4983
private void downHeapify(int pi) {
5084
int lci = 2 * pi + 1;
5185
int rci = 2 * pi + 2;
@@ -62,15 +96,35 @@ private void downHeapify(int pi) {
6296
}
6397
}
6498

99+
/**
100+
* Retrieves the maximum item from the heap without removing it.
101+
*
102+
* @return the maximum item
103+
*/
65104
public T get() {
66-
return this.data.get(0);
105+
if (isEmpty()) {
106+
throw new IllegalStateException("Heap is empty");
107+
}
108+
return this.data.getFirst();
67109
}
68110

69-
// t has higher property then return +ve
111+
/**
112+
* Compares two items to determine their order.
113+
*
114+
* @param t the first item
115+
* @param o the second item
116+
* @return a positive integer if t is greater than o, negative if t is less, and zero if they are equal
117+
*/
70118
private int isLarger(T t, T o) {
71119
return t.compareTo(o);
72120
}
73121

122+
/**
123+
* Swaps two items in the heap and updates their indices in the map.
124+
*
125+
* @param i index of the first item
126+
* @param j index of the second item
127+
*/
74128
private void swap(int i, int j) {
75129
T ith = this.data.get(i);
76130
T jth = this.data.get(j);
@@ -80,9 +134,16 @@ private void swap(int i, int j) {
80134
map.put(jth, i);
81135
}
82136

137+
/**
138+
* Updates the priority of the specified item by restoring the heap property.
139+
*
140+
* @param item the item whose priority is to be updated
141+
*/
83142
public void updatePriority(T item) {
143+
if (!map.containsKey(item)) {
144+
throw new IllegalArgumentException("Item not found in the heap");
145+
}
84146
int index = map.get(item);
85-
// because we enter lesser value then old vale
86147
upHeapify(index);
87148
}
88149
}

src/test/java/com/thealgorithms/datastructures/heaps/GenericHeapTest.java

+39-80
Original file line numberDiff line numberDiff line change
@@ -13,114 +13,73 @@ public class GenericHeapTest {
1313
private GenericHeap<Integer> heap;
1414

1515
@BeforeEach
16-
public void setUp() {
16+
void setUp() {
1717
heap = new GenericHeap<>();
1818
}
1919

2020
@Test
21-
public void testGenericHeapAddAndGet() {
22-
heap.add(19);
23-
heap.add(36);
24-
heap.add(100);
25-
heap.add(-17);
26-
heap.add(3);
27-
28-
// Check that the largest element (100) is at the top of the heap
29-
assertEquals(100, heap.get());
30-
}
31-
32-
@Test
33-
public void testGenericHeapRemove() {
34-
heap.add(19);
35-
heap.add(36);
36-
heap.add(100);
37-
heap.add(-17);
38-
heap.add(3);
39-
40-
// Verify that the largest element is removed correctly
41-
assertEquals(100, heap.remove());
42-
43-
// The new element at the top should be 36
44-
assertEquals(36, heap.get());
21+
void testAddAndGet() {
22+
heap.add(10);
23+
heap.add(20);
24+
heap.add(5);
4525

46-
// Check that the size is correct after removal
47-
assertEquals(4, heap.size());
26+
assertEquals(20, heap.get());
4827
}
4928

5029
@Test
51-
public void testGenericHeapSize() {
52-
assertTrue(heap.isEmpty());
53-
30+
void testRemove() {
5431
heap.add(10);
5532
heap.add(20);
33+
heap.add(5);
5634

57-
// Check that the size is correct
58-
assertEquals(2, heap.size());
59-
60-
heap.remove();
61-
62-
// After removal, the size should be 1
63-
assertEquals(1, heap.size());
35+
assertEquals(20, heap.remove());
36+
assertEquals(10, heap.get());
6437
}
6538

6639
@Test
67-
public void testGenericHeapIsEmpty() {
68-
// Verify that the heap is initially empty
40+
void testIsEmpty() {
6941
assertTrue(heap.isEmpty());
70-
71-
heap.add(15);
72-
73-
// Now the heap should not be empty
42+
heap.add(1);
7443
assertFalse(heap.isEmpty());
75-
76-
heap.remove();
77-
78-
// After removing the one element, it should be empty again
79-
assertTrue(heap.isEmpty());
8044
}
8145

8246
@Test
83-
public void testGenericHeapUpdatePriority() {
84-
heap.add(19);
85-
heap.add(36);
86-
heap.add(100);
87-
heap.add(-17);
88-
heap.add(3);
89-
90-
// Verify that the largest element initially is 100
91-
assertEquals(100, heap.get());
47+
void testSize() {
48+
assertEquals(0, heap.size());
49+
heap.add(1);
50+
heap.add(2);
51+
assertEquals(2, heap.size());
52+
}
9253

93-
heap.remove();
54+
@Test
55+
void testUpdatePriority() {
56+
heap.add(10);
57+
heap.add(20);
58+
heap.add(5);
9459

95-
// Simulates a change in priority by increasing the value of 100 to 44
96-
heap.add(44);
60+
heap.updatePriority(10);
61+
assertEquals(20, heap.get());
9762

98-
// Now, the new high should be 25
99-
assertEquals(44, heap.get());
63+
heap.add(30);
64+
heap.updatePriority(20); // 20 will be moved up
65+
assertEquals(30, heap.get());
10066
}
10167

10268
@Test
103-
public void testGenericHeapRemoveUntilEmpty() {
104-
heap.add(5);
105-
heap.add(3);
106-
heap.add(4);
107-
heap.add(1);
108-
heap.add(2);
109-
110-
// Remove all items and check that they are removed in descending order
111-
assertEquals(5, heap.remove());
112-
assertEquals(4, heap.remove());
113-
assertEquals(3, heap.remove());
114-
assertEquals(2, heap.remove());
115-
assertEquals(1, heap.remove());
69+
void testRemoveFromEmptyHeap() {
70+
Exception exception = assertThrows(IllegalStateException.class, () -> heap.remove());
71+
assertEquals("Heap is empty", exception.getMessage());
72+
}
11673

117-
// Empty heap
118-
assertTrue(heap.isEmpty());
74+
@Test
75+
void testGetFromEmptyHeap() {
76+
Exception exception = assertThrows(IllegalStateException.class, () -> heap.get());
77+
assertEquals("Heap is empty", exception.getMessage());
11978
}
12079

12180
@Test
122-
public void testGenericHeapAddNullItem() {
123-
// Check null item
124-
assertThrows(IllegalArgumentException.class, () -> { heap.add(null); });
81+
void testUpdatePriorityForNonExistentItem() {
82+
Exception exception = assertThrows(IllegalArgumentException.class, () -> heap.updatePriority(100));
83+
assertEquals("Item not found in the heap", exception.getMessage());
12584
}
12685
}

0 commit comments

Comments
 (0)