Bird
Raised Fist0
DSA Cprogramming

Collision Handling Using Chaining in DSA C

Choose your learning style10 modes available
Mental Model
When two keys want the same spot in a table, we keep a list there to hold both.
Analogy: Imagine a mailbox with several slots. If two letters come for the same slot, you put them in a small basket inside that slot instead of throwing one away.
Hash Table:
[0] -> 15 -> 25 -> null
[1] -> null
[2] -> 7 -> 12 -> null
[3] -> null
[4] -> null
Dry Run Walkthrough
Input: Insert keys 15, 25, 7, 12 into a hash table of size 5 using chaining
Goal: Show how collisions are handled by linking nodes in the same bucket
Step 1: Insert 15 at index 15 % 5 = 0
[0] -> 15 -> null
[1] -> null
[2] -> null
[3] -> null
[4] -> null
Why: 15 goes to bucket 0 because 15 mod 5 is 0
Step 2: Insert 25 at index 25 % 5 = 0, collision with 15
[0] -> 15 -> 25 -> null
[1] -> null
[2] -> null
[3] -> null
[4] -> null
Why: 25 also maps to bucket 0, so we add it to the chain after 15
Step 3: Insert 7 at index 7 % 5 = 2
[0] -> 15 -> 25 -> null
[1] -> null
[2] -> 7 -> null
[3] -> null
[4] -> null
Why: 7 goes to bucket 2 with no collision
Step 4: Insert 12 at index 12 % 5 = 2, collision with 7
[0] -> 15 -> 25 -> null
[1] -> null
[2] -> 7 -> 12 -> null
[3] -> null
[4] -> null
Why: 12 also maps to bucket 2, so we add it to the chain after 7
Result:
[0] -> 15 -> 25 -> null
[1] -> null
[2] -> 7 -> 12 -> null
[3] -> null
[4] -> null
Annotated Code
DSA C
#include <stdio.h>
#include <stdlib.h>

#define TABLE_SIZE 5

// Node for linked list in each bucket
typedef struct Node {
    int key;
    struct Node* next;
} Node;

// Hash table with chaining
Node* hashTable[TABLE_SIZE];

// Hash function
int hash(int key) {
    return key % TABLE_SIZE;
}

// Insert key into hash table
void insert(int key) {
    int index = hash(key); // find bucket
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->key = key;
    newNode->next = NULL;

    if (hashTable[index] == NULL) {
        hashTable[index] = newNode; // empty bucket
    } else {
        // collision: add to end of chain
        Node* curr = hashTable[index];
        while (curr->next != NULL) {
            curr = curr->next; // advance to last node
        }
        curr->next = newNode; // link new node
    }
}

// Print the hash table
void printTable() {
    for (int i = 0; i < TABLE_SIZE; i++) {
        printf("[%d] -> ", i);
        Node* curr = hashTable[i];
        while (curr != NULL) {
            printf("%d -> ", curr->key);
            curr = curr->next; // advance in chain
        }
        printf("null\n");
    }
}

int main() {
    // Initialize table
    for (int i = 0; i < TABLE_SIZE; i++) {
        hashTable[i] = NULL;
    }

    // Insert keys
    insert(15);
    insert(25);
    insert(7);
    insert(12);

    // Print final table
    printTable();
    return 0;
}
int index = hash(key); // find bucket
compute bucket index using hash function
if (hashTable[index] == NULL) { hashTable[index] = newNode; // empty bucket } else { Node* curr = hashTable[index]; while (curr->next != NULL) { curr = curr->next; // advance to last node } curr->next = newNode; // link new node }
handle collision by adding new node at end of linked list in bucket
while (curr != NULL) { printf("%d -> ", curr->key); curr = curr->next; // advance in chain }
traverse linked list in bucket to print all keys
OutputSuccess
[0] -> 15 -> 25 -> null [1] -> null [2] -> 7 -> 12 -> null [3] -> null [4] -> null
Complexity Analysis
Time: O(n) in worst case because all keys could hash to same bucket and form a chain, but average O(1) if keys distribute well
Space: O(n) because we store all keys in linked lists inside the table
vs Alternative: Compared to open addressing, chaining uses extra memory for linked lists but handles collisions more flexibly without clustering
Edge Cases
Inserting into an empty bucket
Key is placed directly without collision
DSA C
if (hashTable[index] == NULL) { hashTable[index] = newNode; }
Multiple keys hashing to same bucket
Keys are linked in a chain in that bucket
DSA C
while (curr->next != NULL) { curr = curr->next; } curr->next = newNode;
Printing empty buckets
Prints bucket index followed by null
DSA C
while (curr != NULL) { ... } printf("null\n");
When to Use This Pattern
When you see a hash table with collisions and need to store multiple keys per bucket, use chaining to keep a linked list of keys in each bucket.
Common Mistakes
Mistake: Overwriting existing key in bucket instead of chaining
Fix: Always add new node at end of linked list instead of replacing head
Mistake: Not handling empty bucket case separately
Fix: Check if bucket is NULL before traversing chain
Summary
It stores multiple keys in the same bucket by linking them in a list.
Use it when hash collisions happen and you want to keep all keys safely.
The key is to keep a chain (linked list) at each bucket to hold collided keys.

Practice

(1/5)
1. What is the main idea behind collision handling using chaining in hash tables?
easy
A. Store all elements that hash to the same index in a linked list at that index
B. Replace the existing element with the new one when a collision occurs
C. Use a secondary hash function to find a new index
D. Resize the hash table immediately when a collision happens

Solution

  1. Step 1: Understand collision in hash tables

    When two keys hash to the same index, a collision occurs.
  2. Step 2: Explain chaining method

    Chaining stores all collided elements in a linked list at that index, allowing multiple elements per slot.
  3. Final Answer:

    Store all elements that hash to the same index in a linked list at that index -> Option A
  4. Quick Check:

    Chaining = linked list at index [OK]
Hint: Chaining means linked list at each hash index [OK]
Common Mistakes:
  • Confusing chaining with open addressing
  • Thinking collisions overwrite existing data
  • Believing resizing happens on every collision
2. Which of the following is the correct way to declare a node structure for chaining in C?
easy
A. typedef struct Node { int key; Node* next; } Node;
B. struct Node { int key; int next; };
C. typedef struct Node { int key; struct Node* next; } Node;
D. struct Node { int key; struct Node next; };

Solution

  1. Step 1: Check correct pointer usage in struct

    In C, to create a linked list node, the next pointer must be a pointer to the same struct type.
  2. Step 2: Validate typedef syntax

    typedef struct Node { int key; struct Node* next; } Node; correctly uses struct Node* next; and typedefs the struct as Node.
  3. Final Answer:

    typedef struct Node { int key; struct Node* next; } Node; -> Option C
  4. Quick Check:

    Pointer to struct Node is struct Node* next [OK]
Hint: Use struct Node* for next pointer in C structs [OK]
Common Mistakes:
  • Using struct Node next instead of pointer
  • Missing typedef keyword or incorrect syntax
  • Declaring next as int instead of pointer
3. Consider the following code snippet for inserting keys into a hash table using chaining. What will be the output after inserting keys 5, 15, and 25 if the hash function is key % 10?
typedef struct Node {
  int key;
  struct Node* next;
} Node;

Node* hashTable[10] = {NULL};

void insert(int key) {
  int index = key % 10;
  Node* newNode = malloc(sizeof(Node));
  newNode->key = key;
  newNode->next = hashTable[index];
  hashTable[index] = newNode;
}

// Insert keys
insert(5);
insert(15);
insert(25);

// Print keys at index 5
Node* temp = hashTable[5];
while(temp != NULL) {
  printf("%d -> ", temp->key);
  temp = temp->next;
}
printf("NULL\n");
medium
A. NULL
B. 5 -> 15 -> 25 -> NULL
C. 15 -> 25 -> 5 -> NULL
D. 25 -> 15 -> 5 -> NULL

Solution

  1. Step 1: Calculate hash index for each key

    All keys 5, 15, 25 % 10 = 5, so all go to index 5.
  2. Step 2: Trace insertion order in chaining

    Each new node is inserted at the head, so order is 25 (last inserted), then 15, then 5.
  3. Final Answer:

    25 -> 15 -> 5 -> NULL -> Option D
  4. Quick Check:

    New nodes added at head = 25 -> 15 -> 5 [OK]
Hint: New nodes go to head of list in chaining [OK]
Common Mistakes:
  • Assuming insertion at tail instead of head
  • Miscomputing hash index
  • Printing keys in wrong order
4. The following code for inserting into a chained hash table has a bug. What is the bug?
void insert(int key) {
  int index = key % 10;
  Node newNode;
  newNode.key = key;
  newNode.next = hashTable[index];
  hashTable[index] = &newNode;
}
medium
A. No bug, code is correct
B. newNode is a local variable and will be lost after function ends
C. next pointer is not assigned properly
D. Hash function is incorrect

Solution

  1. Step 1: Identify variable scope issue

    newNode is declared as a local variable on the stack inside insert function.
  2. Step 2: Explain why this causes a bug

    After function returns, newNode memory is invalid, so hashTable points to invalid memory.
  3. Final Answer:

    newNode is a local variable and will be lost after function ends -> Option B
  4. Quick Check:

    Local variable address stored = invalid pointer [OK]
Hint: Use malloc for nodes, not local variables [OK]
Common Mistakes:
  • Ignoring variable lifetime
  • Thinking hash function is wrong
  • Assuming next pointer assignment is incorrect
5. You have a hash table of size 7 using chaining. You insert keys: 10, 21, 17, 14, 28. The hash function is key % 7. After all insertions, which index will have the longest chain and what will be the order of keys in that chain if new nodes are inserted at the head?
hard
A. Index 0: 28 -> 14 -> 21 -> NULL
B. Index 3: 17 -> 14 -> 28 -> NULL
C. Index 3: 14 -> 17 -> 28 -> NULL
D. Index 4: 10 -> 21 -> NULL

Solution

  1. Step 1: Compute hash index for each key

    10 % 7 = 3, 21 % 7 = 0, 17 % 7 = 3, 14 % 7 = 0, 28 % 7 = 0.
  2. Step 2: Group keys by index and order insertion at head

    Index 0 keys inserted in order: 21, then 14, then 28 (last inserted at head). So chain at index 0 is 28 -> 14 -> 21 -> NULL.
    Index 3 keys are 10 and 17.
  3. Final Answer:

    Index 0: 28 -> 14 -> 21 -> NULL -> Option A
  4. Quick Check:

    Longest chain at index 0 with keys inserted at head [OK]
Hint: Calculate key % size, insert new nodes at head [OK]
Common Mistakes:
  • Miscomputing hash indexes
  • Mixing up insertion order in chains
  • Choosing wrong index for longest chain
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard