Gettysburg College

CS 216
Data Structures and Algorithms

Fall 2024

Assignment 4

Due: Mon, Sep 23, by 11:59pm
  • method stubs: CHashMap.java, LHashMap.java, Entry.java
    • with working constructors and toString for the above classes
  • coverage-CHashMap.pdf, coverage-CHashMap.pdf
  • api.pdf only for CHashMap
  • junit tests: CHashMapTest.java and LHashMapTest.java
    • testers confirm that constructors and toString work for empty maps (i.e. as soon as created)
    • use class MyString (see Section Testing at bottom)
    • make sure to read the whole Section Testing at the bottom before writing the JUnit tests
Due: Thu, Sep 26, by 11:59pm
  • CHashMap.java, LHashMap.java, Entry.java
  • CHashMapTest.java, LHashMapTest.java
  • coverage-CHashMap.pdf
  • coverage-LHashMap.pdf

Description

In this assignment you will implement the HashMap data structure. The HashMap can be viewed as a generalization of the primitive array or ArrayList. We still use indices to store data in the HashMap, but here the indices do not need to be sequential, and in fact, the indices do not need to be integers.

For a detailed explanation see the handout on Moodle and the example here:

Hash Map Example

Quick summary:

Inserting in a HashMap
Calculate the bucket index i where the item would have been inserted: Searching in a HashMap
Calculate the bucket index i where the item would have been inserted: Deleting from a HashMap
Calculate the bucket index i where the item would have been inserted:

Testing

See Section "Testing" at the very bottom.

Implementation

Create two separate projects called CHashMap and LHashMap that implement the methods given below using the Chaining and Linear Probing collision resolution schemes:

Keep in mind that you will need to:

The Entry Class

This class has only two data members (key and value) that can be accessed directly. This class is loosely an analog of Node for LinkedList.

For this assignment Entry will be an external class, i.e. in its own file. It is a generic class on two types <K, V> (for comparison, the LinkedList was generic on only one type <E>). Since the class is external, when used it needs to be written as Entry<K, V>, i.e. with explicit generic type K and V, unlike Node which was internal, so the generic type E was implicit and was not written.

The Entry class has method toString that returns the contents in this format:

cat:4

assuming the entry has key "cat" and value "4".

The Map Methods

Setup

Use a primitive array for the buckets:

data member sectionconstructor
LHashMap
Entry<K, V>[] _array-name_;
_array-name_ = (Entry<K, V>[]) new Entry[ ... ];
CHashMap
LinkedList<Entry<K, V>>[] _array-name_;
_array-name_ = (LinkedList<Entry<K, V>>[]) new LinkedList[ ... ];
  • Each map needs to have a data member to keep track of the size (i.e. number of entries)

  • LHashMap needs to have two Entry data members to represent the Empty and Deleted buckets; this is similar to the dummy node in the LinkedList, but now the "dummies" are data members

  • use enhanced for-loop wherever possible

  • none of the methods throw exceptions; instead they return null to indicate "failure"
?HashMap(int initialCapacity, double loadFactor)

Creates a map with the given capacity and load factor; make sure to put empty buckets in the hash map container (empty lists for Chaining, Empty marker for Linear Probing).

The loadFactor is a number in [0..1]. Initially, just assign it and ignore it.

boolean isEmpty()

Determines if the map is empty; this method must run in time O(1), i.e. no loops.
int size()

Returns the number of key/value pairs stored in this map. This method must run in time O(1), i.e. no loops. The methods put and remove should keep track of the current size.
V put(K key, V value)

Puts the given value under the given key and returns the old value associated with this key.
V get(K key)

Returns the value associated with the given key.
V remove(K key)

Removes/deletes the entry with the given key from the map and returns the entry's value.
void clear()

clears the map
boolean containsKey(K key)

Determines if the map contains an element with the given key/index.
boolean containsValue(V value)

Determines if the map contains the given value.

For LHashMap implement this using the iterator over the values in the map. This method will indirectly test the iterator. Use enhanced for loop.

void rehash()

(private) Expands the map storage (after adding new entry) if size ≥ load_factor * capacity. Rehashes all the key/value pairs (cannot simply copy the entries to the same indices indices).

The effect of rehashing is to double the map capacity (twice as many buckets) and to rearrange the entries, as if someone collected all entries in left-to-right, top-to-bottom order and put them in an initially empty map.

String toString()

Returns a string representation of the map. Here are examples of maps with capacity 10 -- one map has 4 entries and the other map is empty, i.e. it has no entries, but it does have buckets:
  • for LHashMap returns (letter E is placed for Empty marker, letter D for Deleted marker)

    4:[D E 76544632:mickey 14742300:donald D 67587658:minnie E E D 22571632:tom]
    0:[E E E E E E] (for empty map)

  • for CHashMap returns:

    4:[[] [] [] [] [76544632:mickey 14742300:donald 67587658:minnie] [] [] [22571632:tom] [] []]
    0:[[] [] [] [] [] [] [] [] [] []] (for empty map)

  • the first number is the size of the map, i.e. number of entries, not number of buckets

  • in CHashMapTest and LHashMapTest, respectively, create an empty map of n buckets and assert that you got the correct string

  • avoid if statements and only one loop is needed in each case, since LinkedList and Entry have method toString, so you can simply write:

    LHashMap:      str = str + entry

    CHashMap:      str = str + list_of_entries

    in CHashMap there will be commas, so to remove at the end write:

    str = str.replaceAll(",", "")

Iterator<V> iterator()

Returns an iterator over the values stored in this map from the first bucket to the last; operation remove is not implemented.

You are only expected to implement iterator for LHashMap class. This will be similar to the Stack iterator, but hasNext() will have a loop.

Include test cases for the failing condition(s) of the iterator (recreate the map for different types of conditions.).

Testing

For testing:


What to turn in

Upload the .java and .pdf files in the Moodle dropbox. (Do NOT upload .html files.)