Skip to content

Commit a9dd6b2

Browse files
committed
Bag implementation
1 parent 0f28479 commit a9dd6b2

File tree

5 files changed

+516
-4
lines changed

5 files changed

+516
-4
lines changed

README.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ Below topics/problems are covered as of now.
122122
- [ ] HashList Implementation
123123
- [ ] Dictionary Implementation
124124
- [ ] MultiMap
125-
- [ ] Bag
126125

127126
**12. Set**
128127
- [X] [Introduction](../master/src/com/deepak/data/structures/Set/SetIntroduction.md)
@@ -149,15 +148,20 @@ Below topics/problems are covered as of now.
149148
- [X] [LRU Cache](../master/src/com/deepak/data/structures/Cache/LRUCache.java)
150149
- [X] [MRU Cache](../master/src/com/deepak/data/structures/Cache/MRUCache.java)
151150

152-
**17. Common Utils**
151+
**17. Miscellaneous**
152+
- [ ] Bag
153+
- [X] [Linked List Based](../master/src/com/deepak/data/structures/Bag/CustomBagLL.java)
154+
- [ ] Binary Search Tree Based
155+
156+
**18. Common Utils**
153157
- [X] [StringUtils](../master/src/com/deepak/data/structures/Utils/StringUtils.java)
154158
- [X] [NumberUtils](../master/src/com/deepak/data/structures/Utils/NumberUtils.java)
155159
- [X] [ArrayUtils](../master/src/com/deepak/data/structures/Utils/ArrayUtils.java)
156160
- [X] [BooleanUtils](../master/src/com/deepak/data/structures/Utils/BooleanUtils.java)
157161
- [X] [CollectionUtils](../master/src/com/deepak/data/structures/Utils/CollectionUtils.java)
158162
- [X] [MapUtils](../master/src/com/deepak/data/structures/Utils/MapUtils.java)
159163

160-
**18. Iterators**
164+
**19. Iterators**
161165
- [X] [Standard Iterator](../master/src/com/deepak/data/structures/Iterators/StandardIterator.java)
162166
- [ ] Deep Iterator
163167
- [ ] Filtering Iterator
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.deepak.data.structures.Bag;
2+
3+
public class CustomBagBST {
4+
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
/**
2+
* Data-Structures-In-Java
3+
* CustomBagLL.java
4+
*/
5+
package com.deepak.data.structures.Bag;
6+
7+
import java.util.Iterator;
8+
import java.util.NoSuchElementException;
9+
import java.util.Random;
10+
11+
/**
12+
* Custom bag implementation using a Linked List
13+
*
14+
* @author Deepak
15+
*
16+
* @param <T>
17+
*/
18+
public class CustomBagLL<T> {
19+
20+
public static void main(String[] args) {
21+
CustomBagLL<String> bag = new CustomBagLL<>();
22+
System.out.println(bag.isEmpty());
23+
bag.add("A");
24+
bag.add("C");
25+
bag.add("B");
26+
bag.add("B");
27+
bag.add("A");
28+
bag.add("B");
29+
System.out.println(bag.toString());
30+
bag.remove("C");
31+
System.out.println(bag.toString());
32+
bag.remove("A");
33+
System.out.println(bag.toString());
34+
System.out.println("Bag contains C : " + bag.contains("C"));
35+
System.out.println("Bag contains B : " + bag.contains("B"));
36+
System.out.println("Bag Size : " + bag.size());
37+
System.out.println("Bag Distinct Size : " + bag.distinctSize());
38+
System.out.println("Grab : " + bag.grab());
39+
Iterator<String> itr = bag.iterator();
40+
/* Starting to print from iterator */
41+
System.out.println();
42+
System.out.println("Printing from iterator : ");
43+
while (itr.hasNext()) {
44+
System.out.println(itr.next());
45+
}
46+
}
47+
48+
/* Head node */
49+
private Node<T> head;
50+
51+
/**
52+
* Constructor
53+
*/
54+
public CustomBagLL() {
55+
this.head = null;
56+
}
57+
58+
/**
59+
* Method to add a item
60+
*
61+
* @param item
62+
*/
63+
public void add(T item) {
64+
/* If bag is empty, make new item as head */
65+
if (isEmpty()) {
66+
Node<T> newNode = new Node<T>(item);
67+
head = newNode;
68+
} else {
69+
/* Have two pointers current and last */
70+
Node<T> current = head;
71+
Node<T> last = head;
72+
boolean found = false;
73+
while (current != null) {
74+
/* If that item is found, just increase the value */
75+
if (current.item == item) {
76+
current.incrementValue();
77+
found = true;
78+
break;
79+
}
80+
last = current;
81+
current = current.next;
82+
}
83+
/* If not found, create as a new node and push to last */
84+
if (!found) {
85+
Node<T> newNode = new Node<T>(item);
86+
last.next = newNode;
87+
}
88+
}
89+
}
90+
91+
/**
92+
* Method to remove a item
93+
*
94+
* @param item
95+
* @return {@link boolean}
96+
*/
97+
public boolean remove(T item) {
98+
/* If bag contains the item */
99+
if (contains(item)) {
100+
/* Have two pointers current and prev */
101+
Node<T> current = head;
102+
Node<T> prev = head;
103+
/* Keep going while current is not null */
104+
while (current != null) {
105+
if (current.item == item) {
106+
/* If item matches, check if it is a head or not */
107+
if (current == head) {
108+
/* If it's head, decrement the value and update head */
109+
current.decrementValue();
110+
if (current.value < 1) {
111+
head = head.next;
112+
}
113+
return true;
114+
} else {
115+
/* Decrement the value, check if this was the last
116+
* entry of that type, it yes, delete the item */
117+
current.decrementValue();
118+
if (current.value < 1) {
119+
prev.next = current.next;
120+
current.next = null;
121+
}
122+
return true;
123+
}
124+
}
125+
/* Move to next set of items */
126+
prev = current;
127+
current = current.next;
128+
}
129+
}
130+
return false;
131+
}
132+
133+
/**
134+
* Method to clear the bag
135+
*/
136+
public void clear() {
137+
this.head = null;
138+
}
139+
140+
/**
141+
* Method to check if bag contains the item
142+
*
143+
* @param item
144+
* @return {@link boolean}
145+
*/
146+
public boolean contains(T item) {
147+
Node<T> current = head;
148+
/* Start traversing and stop if item matches */
149+
while (current != null) {
150+
if (current.item == item) {
151+
return true;
152+
}
153+
current = current.next;
154+
}
155+
return false;
156+
}
157+
158+
/**
159+
* Method to grab any random element
160+
*
161+
* @return {@link T}
162+
*/
163+
public T grab() {
164+
/* Have a random index */
165+
Random random = new Random();
166+
int randomItemIndex = random.nextInt(distinctSize());
167+
Node<T> current = head;
168+
/* Move the pointer till we reach that random index */
169+
for (int i = 0; i < randomItemIndex; i++) {
170+
current = current.next;
171+
}
172+
return current.item;
173+
}
174+
175+
/**
176+
* Method to check size of the bag
177+
*
178+
* @return {@link int}
179+
*/
180+
public int size() {
181+
Node<T> current = head;
182+
int size = 0;
183+
/* Keep traversing and track size of each entry */
184+
while (current != null) {
185+
size += current.value;
186+
current = current.next;
187+
}
188+
return size;
189+
}
190+
191+
/**
192+
* Method to get distinct size of the bag
193+
*
194+
* @return {@link int}
195+
*/
196+
public int distinctSize() {
197+
Node<T> current = head;
198+
int counter = 0;
199+
/* Increment the counter only when a new element is seen */
200+
while (current != null) {
201+
counter++;
202+
current = current.next;
203+
}
204+
return counter;
205+
}
206+
207+
/**
208+
* Method to check if bag is empty
209+
*
210+
* @return {@link boolean}
211+
*/
212+
public boolean isEmpty() {
213+
if (head == null) {
214+
return true;
215+
}
216+
return false;
217+
}
218+
219+
/**
220+
* Method to print the content of bag as string
221+
*/
222+
public String toString() {
223+
if (isEmpty()) {
224+
return "Bag is Empty";
225+
} else {
226+
/* Keep appending the elements to string */
227+
Node<T> current = head;
228+
String str = "Bag = ";
229+
while (current != null) {
230+
for (int i = 0; i < current.value; i++) {
231+
str += "{" + current.item + "}";
232+
}
233+
current = current.next;
234+
}
235+
return str;
236+
}
237+
}
238+
239+
/**
240+
* Method to get a iterator on bag
241+
*
242+
* @return {@link Iterator<T>}
243+
*/
244+
public Iterator<T> iterator() {
245+
return new Iterator<T>() {
246+
247+
/* Keep a track of next item and value count for each item */
248+
private Node<T> nextItem = head;
249+
private int valueCount = 0;
250+
251+
/**
252+
* Method to check if bag has elements
253+
*/
254+
@Override
255+
public boolean hasNext() {
256+
/* If next item is head and it's not null,
257+
* we have more elements */
258+
if (nextItem == head && nextItem != null) {
259+
return true;
260+
} else if (nextItem != head && nextItem.next != null){
261+
return true;
262+
} else if (nextItem.value > valueCount + 1) {
263+
return true;
264+
}
265+
return false;
266+
}
267+
268+
/**
269+
* Method to get the next element
270+
*/
271+
@Override
272+
public T next() {
273+
if (!hasNext()) {
274+
throw new NoSuchElementException("No Element left in collection");
275+
}
276+
if (nextItem.value > valueCount) {
277+
/* We still have items of same type left */
278+
valueCount++;
279+
} else {
280+
/* Time to move to next item */
281+
nextItem = nextItem.next;
282+
valueCount = 0;
283+
}
284+
Node<T> itemToReturn = nextItem;
285+
if (itemToReturn != null) {
286+
return itemToReturn.item;
287+
} else {
288+
return null;
289+
}
290+
}
291+
292+
};
293+
}
294+
295+
/**
296+
* Class Node for Bag
297+
*
298+
* @author Deepak
299+
*
300+
* @param <E>
301+
*/
302+
public class Node<E> {
303+
304+
/* Item, counter associated with item and next pointer */
305+
private E item;
306+
private int value;
307+
private Node<E> next;
308+
309+
/**
310+
* Constructor to create the Node
311+
*
312+
* @param item
313+
*/
314+
public Node(E item) {
315+
this.item = item;
316+
this.value = 1;
317+
this.next = null;
318+
}
319+
320+
/**
321+
* Method to increment the value
322+
*/
323+
public void incrementValue() {
324+
value++;
325+
}
326+
327+
/**
328+
* Method to decrement the value
329+
*/
330+
public void decrementValue() {
331+
value--;
332+
}
333+
334+
@Override
335+
public String toString() {
336+
return "Item : [" + this.item + "]";
337+
}
338+
339+
}
340+
341+
}

src/com/deepak/data/structures/Hashing/CustomHashMap.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Data-Structures-And-Algorithms-in-Java
2+
* Data-Structures-In-Java
33
* CustomHashMap.java
44
*/
55
package com.deepak.data.structures.Hashing;

0 commit comments

Comments
 (0)