Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added hashmap implementation (with linked list) #222

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions Hashmaps/implementation/HashMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package implementation;

import java.util.LinkedList;
public class HashMap<K, V> {
class HashElement<K, V> implements Comparable<HashElement<K, V>> {
K key;
V value;

public HashElement(K key, V value) {
this.key = key;
this.value = value;
}

public K getKey() { return key; }

public V getValue() { return value; }

@Override
public int compareTo(HashElement<K, V> otherHashElement) {
return ((Comparable<K>)this.key).compareTo(otherHashElement.key);
}
}

int elementSize = 0;
int tableSize;
double maxLoadFactor;
LinkedList<HashElement<K, V>>[] hashtable;

public HashMap(int tableSize) {
this.tableSize = tableSize;
this.hashtable = (LinkedList<HashElement<K, V>>[]) new LinkedList
[tableSize]; // Fixed array initialization
this.maxLoadFactor = 0.75;
this.elementSize = 0;
for (int i = 0; i < tableSize; i++) {
this.hashtable[i] = new LinkedList<>();
}
}

// associative array for fast search and removal
// one for key another for value

// hash function is property of data
// fast, low collision
// equal return same value
public int hashCode(String s, int tableSize) {
int g = 31;
int hash = 0;
for (int i = 0; i < s.length(); i++) {
hash = g * hash + s.charAt(i);
}
// if modulo result is negative -> change the first bit
// to dissolve negative , number & 0X07FFFFFFF
return hash % tableSize;
}

public int hashIndex(int hash) { return (hash & 0x7FFFFFFF) % tableSize; }
// to avoid collision
// odd sized or prime number table

public boolean add(K key, V value) {
if (getLoadFactor() > maxLoadFactor) {
resize(tableSize * 2);
}

int index = hashIndex(key.hashCode()); // index to add
if (hashtable[index] == null) {
hashtable[index] =
new LinkedList<>(); // Create a new LinkedList if it doesn't exist
}
HashElement<K, V> newHash = new HashElement<>(key, value);
hashtable[index].add(newHash);
elementSize++;
return true;
}

public double getLoadFactor() { return (double)elementSize / tableSize; }

public void resize(int newTableSize) {
LinkedList<HashElement<K, V>>[] newTable =
(LinkedList<HashElement<K, V>>[]) new LinkedList[newTableSize];
for (int i = 0; i < newTableSize; i++) {
newTable[i] = new LinkedList<>();
}

for (LinkedList<HashElement<K, V>> list : hashtable) {
if (list != null) {
for (HashElement<K, V> element : list) {
int index = hashIndex(element.getKey().hashCode());
newTable[index].add(element);
}
}
}
tableSize = newTableSize;
hashtable = newTable;
}

public V getvalue(K key) {
int index = hashIndex(key.hashCode());
LinkedList<HashElement<K, V>> current = hashtable[index];

if (current != null) {
for (var element : current) {
if (element.getKey().equals(key)) {
return element.getValue();
}
}
}
return null;
}
}
96 changes: 96 additions & 0 deletions Hashmaps/implementation/LinkedList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package implementation;

public class LinkedList<E> {
class Node<E> {
E data;
Node<E> next;

public Node(E data) {
this.data = data;
next = null;
}
}

private Node<E> head;
private int size;

public LinkedList() {
head = null;
size = 0;
}

public void prepend(E data) {
Node<E> node = new Node<E>(data);
node.next = head;
head = node;
size++;
}

public void removeFirst() {
if (head == null)
return;
head = head.next;
}

public void add(E data) {
Node<E> node = new Node<E>(data);
if (head == null) {
head = node;
size++;
return;
}

Node<E> current = head;
while (current.next != null) {
current = current.next;
}
current.next = node;
size++;
}
public void removeLast() {
if (head == null)
return;

// head == tail, removeFirst
if (head.next == null) {
removeFirst();
return;
}

Node<E> current = head;
Node<E> previous = null;

while (current.next != null) {
previous = current;
current = current.next;
}

previous.next = null;
size--;
}

public void remove(E data) {
if (head == null) {
return; // List is empty
}

if (head.data.equals(data)) {
// If the data to remove is in the head node, remove the head
removeFirst();
return;
}

Node<E> current = head;
Node<E> previous = null;

while (current != null && !current.data.equals(data)) {
previous = current;
current = current.next;
}

if (current != null) {
previous.next = current.next;
size--;
}
}
}