Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Design HashMap in Python
A HashMap is a key-value data structure that provides fast lookups, insertions, and deletions. We can implement a custom HashMap in Python using an array of linked lists to handle collisions through chaining.
HashMap Operations
Our HashMap will support three main operations ?
-
put(key, value)− Insert or update a key-value pair -
get(key)− Retrieve the value for a given key, return -1 if not found -
remove(key)− Delete a key-value pair from the HashMap
Implementation Strategy
We'll use separate chaining to handle hash collisions. Each bucket in our hash table contains a linked list of key-value pairs.
Node Class
First, we create a Node class to store key-value pairs in our linked lists ?
class Node:
def __init__(self, key, val):
self.key = key
self.val = val
self.next = None
LinkedList Class
Each bucket uses a linked list to handle collisions ?
class LinkedList:
def __init__(self):
self.prehead = Node(None, None) # Dummy head node
def search(self, key):
p = self.prehead.next
while p:
if p.key == key:
return p
p = p.next
return None
def add(self, key, val):
p = self.search(key)
if p:
p.val = val # Update existing key
else:
node = Node(key, val)
node.next = self.prehead.next
self.prehead.next = node # Insert at beginning
def get(self, key):
p = self.search(key)
return p.val if p else None
def remove(self, key):
prev = self.prehead
cur = prev.next
while cur:
if cur.key == key:
prev.next = cur.next
break
prev, cur = cur, cur.next
MyHashMap Class
Now we implement the main HashMap class ?
class MyHashMap:
def __init__(self):
self.size = 1033 # Prime number for better distribution
self.arr = [LinkedList() for _ in range(self.size)]
def _hash(self, key):
return key % self.size
def put(self, key, value):
h = self._hash(key)
self.arr[h].add(key, value)
def get(self, key):
h = self._hash(key)
ret = self.arr[h].get(key)
return ret if ret is not None else -1
def remove(self, key):
h = self._hash(key)
self.arr[h].remove(key)
# Test the HashMap implementation
hashmap = MyHashMap()
hashmap.put(1, 1)
hashmap.put(2, 2)
print(hashmap.get(1)) # Output: 1
print(hashmap.get(3)) # Output: -1 (not found)
hashmap.put(2, 1) # Update value
print(hashmap.get(2)) # Output: 1
hashmap.remove(2) # Remove key
print(hashmap.get(2)) # Output: -1 (removed)
1 -1 1 -1
How It Works
The HashMap uses separate chaining for collision resolution. When multiple keys hash to the same bucket, they are stored in a linked list at that position. The hash function key % 1033 distributes keys across 1033 buckets.
Time Complexity
| Operation | Average Case | Worst Case |
|---|---|---|
| Put | O(1) | O(n) |
| Get | O(1) | O(n) |
| Remove | O(1) | O(n) |
Conclusion
This HashMap implementation uses separate chaining with linked lists to handle collisions efficiently. The prime number 1033 for bucket size helps distribute keys evenly and minimize collisions.
