Bird
Raised Fist0
DSA Cprogramming~5 mins

Collision Handling Using Chaining in DSA C - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Collision Handling Using Chaining
O(1 + n/k)
Understanding Time Complexity

When we use chaining to handle collisions in a hash table, we want to know how fast operations like search, insert, and delete run.

We ask: How does the time to do these operations grow as the number of items increases?

Scenario Under Consideration

Analyze the time complexity of inserting a key into a hash table using chaining.


// Insert key into hash table with chaining
void insert(HashTable* ht, int key) {
    int index = hashFunction(key, ht->size);
    Node* newNode = createNode(key);
    newNode->next = ht->buckets[index];
    ht->buckets[index] = newNode;
}
    

This code adds a new key at the start of the linked list in the bucket found by the hash function.

Identify Repeating Operations

In chaining, the main repeating operation happens when searching or deleting keys in a bucket's linked list.

  • Primary operation: Traversing the linked list in a bucket.
  • How many times: Depends on the number of keys in that bucket, which varies with total keys and hash distribution.
How Execution Grows With Input

As more keys are added, linked lists in buckets get longer if the table size stays the same.

Input Size (n)Approx. Operations (list length)
101 to 2
1005 to 10
100050 to 100

Pattern observation: Without resizing, the linked list length grows roughly proportional to the number of keys, making operations slower.

Final Time Complexity

Time Complexity: O(1 + n/k) where n is total keys and k is number of buckets.

This means operations take constant time plus time proportional to the average number of keys per bucket.

Common Mistake

[X] Wrong: "Chaining always gives constant time operations regardless of input size."

[OK] Correct: If many keys hash to the same bucket, the linked list grows, making operations slower than constant time.

Interview Connect

Understanding how chaining affects time helps you explain hash table performance clearly and shows you know how to handle collisions well.

Self-Check

What if we doubled the number of buckets as keys increase? How would the time complexity change?

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