Skip to content

Commit 15ae8e5

Browse files
committed
chore: resolve checkstyle issues
1 parent 123c8cc commit 15ae8e5

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

src/main/java/dataStructures/hashSet/openAddressing/HashSet.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public boolean add(T element) {
8787
// This line will only be reached if the number of empty buckets is zero.
8888
// With the resizing mechanism, the HashSet/buckets will expand to a larger capacity when a
8989
// certain threshold is reached. This means that there will always be empty buckets for adding of elements.
90-
assert false: "should never reach this line under normal circumstances, due to resizing mechanism";
90+
assert false : "should never reach this line under normal circumstances, due to resizing mechanism";
9191
return false;
9292
}
9393

@@ -318,6 +318,11 @@ private boolean isLoadFactorExceeded() {
318318
return this.size() >= this.capacity() * LOAD_FACTOR;
319319
}
320320

321+
/**
322+
* Returns the singleton instance of Tombstone. Should never be called outside of tests.
323+
*
324+
* @return the singleton instance of Tombstone.
325+
*/
321326
public T tombstone() {
322327
// It is safe to cast Tombstone to T, because methods retrieving elements (HashSet::get) from the HashSet
323328
// should, and will check whether the item is a Tombstone object, returning null in-place of the Tombstone.

src/main/java/dataStructures/hashSet/openAddressing/README.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@ the array (the probe sequence) until either the target element is found, or an u
77
which indicates that there is no such key in the table.
88

99
## Implementation Invariant
10+
1011
Note that the buckets are 1-indexed in the following explanation.
1112

12-
Invariant: Probe sequence is unbroken. That is to say, given an element that is initially hashed to
13+
Invariant: Probe sequence is unbroken. That is to say, given an element that is initially hashed to
1314
bucket 1 (arbitrary), the probe sequence {1, 2, ..., m} generated when attempting to `add`/`remove`/`find`
1415
the element will ***never*** contain null.
1516

1617
This invariant is used to help us ensure the correctness and efficiency of `add`/`remove`/`contains`.
17-
With the above example of an element generating a probe sequence {1, 2, ...}, `add` will check each bucket
18-
sequentially, attempting to add the element, treating buckets containing `Tombstones` (to be explained later) and
19-
`nulls` as **empty** buckets available for insertion.
18+
With the above example of an element generating a probe sequence {1, 2, ...}, `add` will check each bucket
19+
sequentially, attempting to add the element, treating buckets containing `Tombstones` (to be explained later) and
20+
`nulls` as **empty** buckets available for insertion.
2021

2122
As a result, if the bucket is inserted in bucket `m`, such that the probe sequence {1, 2, ..., m} is
2223
generated, then there must have been elements occupying buckets {1, 2, ..., m - 1}, resulting in collisions.
@@ -26,13 +27,14 @@ simply replacing the element to be removed with `null` will cause `contains` to
2627
was present.
2728

2829
`Tombstones` allow us to mark the bucket as deleted, which allows `contains` to know that there is a
29-
possibility that the targeted element can be found later in the probe sequence, returning false immediately upon
30+
possibility that the targeted element can be found later in the probe sequence, returning false immediately upon
3031
encountering `null`.
3132

3233
We could simply look into every bucket in the sequence, but that will result in `remove` and `contains` having an O(n)
3334
runtime complexity, defeating the purpose of hashing.
3435

35-
TLDR: There is a need to differentiate between deleted elements, and `nulls` to ensure operations on the Set have an O(1)
36+
TLDR: There is a need to differentiate between deleted elements, and `nulls` to ensure operations on the Set have an O(
37+
1)
3638
time complexity.
3739

3840
## Probing Strategies
@@ -80,10 +82,12 @@ For n items, in a table of size m, assuming uniform hashing, the expected cost o
8082
e.g. if α = 90%, then E[#probes] = 10;
8183

8284
## Properties of Good Hash Functions
85+
8386
There are two properties to measure the "goodness" of a Hash Function
87+
8488
1. h(key, i) enumerates all possible buckets.
85-
- For every bucket j, there is some i such that: h(key, i) = j
86-
- The hash function is a permutation of {1..m}.
89+
- For every bucket j, there is some i such that: h(key, i) = j
90+
- The hash function is a permutation of {1..m}.
8791

8892
Linear probing satisfies the first property, because it will probe all possible buckets in the Set. I.e. if an element
8993
is initially hashed to bucket 1, in a Set with capacity n, linear probing generates a sequence of {1, 2, ..., n - 1, n},
@@ -96,6 +100,6 @@ enumerating every single bucket.
96100
- Linear Probing does ***NOT*** fulfil UHA. In linear probing, when a collision occurs, the HashSet handles it by
97101
checking the next bucket, linearly until an empty bucket is found. The next slot is always determined in a fixed
98102
linear manner.
99-
- In practicality, achieving UHA is difficult. Double hashing can come close to achieving UHA, by using another
103+
- In practicality, achieving UHA is difficult. Double hashing can come close to achieving UHA, by using another
100104
hash function to vary the step size (unlike linear probe where the step size is constant), resulting in a more
101105
uniform distribution of keys and better performance for the hash table.

0 commit comments

Comments
 (0)