Total Pageviews

Wednesday, July 1, 2026

Recursion

 










📘 Module 4: Recursion (5 Lectures)




🎓 Module 4: Recursion

Total Lectures: 5


📖 Lecture 1: Introduction to Recursion

<div style="background:#E3F2FD;padding:15px;border-left:8px solid #1976D2;border-radius:8px;">

🔹 What is Recursion?

Recursion is a programming technique in which a function calls itself to solve a problem.

Instead of using loops (for, while), recursion repeatedly breaks a problem into smaller subproblems until a stopping condition (called the Base Case) is reached.

</div>

🎯 Real-Life Examples

📂 Opening a folder inside another folder.

🪞 Looking into two mirrors facing each other.

🪆 Russian Dolls (Matryoshka Dolls)

🏢 Climbing stairs one step at a time.


General Syntax

return_type function_name(parameters)
{
if(base_condition)
return value;

return function_name(smaller_problem);
}

Basic Structure of Recursion

            Function Call

Is Base Case True?
/ \
Yes No
│ │
Return Result Call Same Function

Smaller Problem

Important Terms

TermMeaning
Recursive FunctionFunction that calls itself
Base CaseStops recursion
Recursive CallFunction calling itself
Call StackStores function calls

Example 1: Print Numbers from 1 to 5

#include<stdio.h>

void print(int n)
{
if(n>5)
return;

printf("%d ",n);

print(n+1);
}

int main()
{
print(1);
return 0;
}

Output

1 2 3 4 5

Example 2: Countdown

#include<stdio.h>

void countdown(int n)
{
if(n==0)
return;

printf("%d ",n);

countdown(n-1);
}

int main()
{
countdown(5);
}

Output

5 4 3 2 1

📖 Lecture 2: Developing Recursive Definition of Simple Problems


Steps to Develop Recursive Solution

<div style="background:#FFF3E0;padding:15px;border-left:8px solid orange;border-radius:8px;">

Step 1

Identify the smallest problem.

Step 2

Find the Base Case.

Step 3

Reduce the problem.

Step 4

Call the function again.

</div>

Example 1: Factorial

Mathematical Definition

5! = 5×4×3×2×1

n! = n × (n-1)!

0! = 1

Algorithm

factorial(n)

if n==0
return 1

return n * factorial(n-1)

Program

#include<stdio.h>

int factorial(int n)
{
if(n==0)
return 1;

return n*factorial(n-1);
}

int main()
{
printf("%d",factorial(5));
}

Output

120

Example 2: Sum of First N Numbers

Sum(5)

5+4+3+2+1

=5+Sum(4)

Program

#include<stdio.h>

int sum(int n)
{
if(n==0)
return 0;

return n+sum(n-1);
}

int main()
{
printf("%d",sum(5));
}

Output

15

Example 3: Power

2^5

=2 × Power(2,4)

Program

#include<stdio.h>

int power(int a,int b)
{
if(b==0)
return 1;

return a*power(a,b-1);
}

int main()
{
printf("%d",power(2,5));
}

Output

32

📖 Lecture 3: Advantages and Limitations of Recursion


🌟 Advantages

<div style="background:#E8F5E9;padding:15px;border-left:8px solid green;border-radius:8px;">

✔ Simple Code

✔ Easy to Understand

✔ Less Coding

✔ Suitable for Tree Problems

✔ Useful in Graph Algorithms

✔ Natural Solution for Divide & Conquer

✔ Cleaner than loops in many algorithms

</div>

Applications

ApplicationExample
Tree TraversalInorder, Preorder
Graph SearchDFS
SortingMerge Sort
SearchingBinary Search
MathematicsFactorial
Dynamic ProgrammingMemoization
CompilerParsing

⚠ Limitations

<div style="background:#FFEBEE;padding:15px;border-left:8px solid red;border-radius:8px;">

❌ More Memory

❌ Function Call Overhead

❌ Slower than Loops

❌ Stack Overflow

❌ Difficult Debugging

❌ Infinite Recursion if Base Case Missing

</div>

Comparison

FeatureIterationRecursion
Uses LoopYesNo
Uses StackNoYes
SpeedFasterSlower
MemoryLessMore
CodeLongerShorter
DebuggingEasyDifficult

📖 Lecture 4: Understanding Internal Stack Implementation


Every Recursive Call Creates

✔ Parameters

✔ Local Variables

✔ Return Address

✔ Function State

All are stored inside the Call Stack.


Example

factorial(4)

Calls

factorial(4)



factorial(3)



factorial(2)



factorial(1)



factorial(0)

Stack Formation

Top

factorial(0)

factorial(1)

factorial(2)

factorial(3)

factorial(4)

Bottom

Returning Phase

factorial(0)=1



factorial(1)=1×1



factorial(2)=2×1



factorial(3)=3×2



factorial(4)=4×6=24

Visual Diagram

CALLS

main()



fact(4)



fact(3)



fact(2)



fact(1)



fact(0)

-------------------

RETURNS

1



1



2



6



24

Stack Memory Illustration

+--------------------+
| factorial(0) |
+--------------------+
| factorial(1) |
+--------------------+
| factorial(2) |
+--------------------+
| factorial(3) |
+--------------------+
| factorial(4) |
+--------------------+
| main() |
+--------------------+

📖 Lecture 5: Programs Using Recursion


Program 1: Fibonacci Series

#include<stdio.h>

int fib(int n)
{
if(n<=1)
return n;

return fib(n-1)+fib(n-2);
}

int main()
{
int i;

for(i=0;i<10;i++)
printf("%d ",fib(i));
}

Output

0 1 1 2 3 5 8 13 21 34

Program 2: Reverse a Number

#include<stdio.h>

void reverse(int n)
{
if(n==0)
return;

printf("%d",n%10);

reverse(n/10);
}

int main()
{
reverse(12345);
}

Output

54321

Program 3: Print Array

#include<stdio.h>

void display(int a[],int n,int i)
{
if(i==n)
return;

printf("%d ",a[i]);

display(a,n,i+1);
}

int main()
{
int a[]={10,20,30,40};

display(a,4,0);
}

Output

10 20 30 40

Program 4: GCD Using Recursion

#include<stdio.h>

int gcd(int a,int b)
{
if(b==0)
return a;

return gcd(b,a%b);
}

int main()
{
printf("%d",gcd(18,12));
}

Output

6

Program 5: Decimal to Binary

#include<stdio.h>

void binary(int n)
{
if(n==0)
return;

binary(n/2);

printf("%d",n%2);
}

int main()
{
binary(13);
}

Output

1101

🎯 Viva Questions

  1. Define recursion.
  2. What is a recursive function?
  3. What is the base case?
  4. Why is the base case necessary?
  5. Explain the recursive case.
  6. What is a call stack?
  7. Why can recursion cause stack overflow?
  8. Differentiate recursion and iteration.
  9. Give real-life examples of recursion.
  10. Explain internal stack implementation with an example.

📌 Interview Questions

  • Can every recursive program be converted into an iterative program?
  • Why is recursion slower than iteration?
  • What is tail recursion?
  • What is indirect recursion?
  • How does the compiler manage recursive function calls?
  • What happens if the base case is omitted?
  • Which data structure is used internally to implement recursion?




📘 Tail Recursion

🔹 Definition

Tail Recursion is a type of recursion in which the recursive function call is the last statement executed in the function. After the recursive call, no further computation or operation is performed.

In simple words: A function is tail recursive if it immediately returns the result of its recursive call.


🔑 Characteristics of Tail Recursion

  • ✅ The recursive call is the last operation in the function.
  • ✅ No calculation is performed after the recursive call.
  • ✅ Easier for some compilers to optimize (called Tail Call Optimization, although many C compilers do not always apply it).
  • ✅ Generally more memory-efficient when optimized.

📊 General Syntax

return_type function_name(parameters)
{
if (base_condition)
return value;

return function_name(smaller_problem); // Last statement
}

Example 1: Print Numbers from 1 to 5

#include <stdio.h>

void print(int n)
{
if (n > 5)
return;

printf("%d ", n);

print(n + 1); // Last statement
}

int main()
{
print(1);
return 0;
}

Output

1 2 3 4 5

Explanation

  • print(1) prints 1
  • Calls print(2)
  • print(2) prints 2
  • Continues until print(5)
  • Finally reaches the base case when n > 5

Since nothing executes after print(n + 1), this is Tail Recursion.


Example 2: Countdown

#include <stdio.h>

void countdown(int n)
{
if (n == 0)
return;

printf("%d ", n);

countdown(n - 1);
}

int main()
{
countdown(5);
}

Output

5 4 3 2 1

Again, the recursive call is the last statement, so this is Tail Recursion.


Tail Recursive Factorial

A normal factorial function is not tail recursive because multiplication happens after the recursive call.

Tail Recursive Version

#include <stdio.h>

int factorial(int n, int result)
{
if (n == 0)
return result;

return factorial(n - 1, n * result);
}

int main()
{
printf("%d", factorial(5, 1));
return 0;
}

Output

120

How It Works

Function CallResult
factorial(5,1)factorial(4,5)
factorial(4,5)factorial(3,20)
factorial(3,20)factorial(2,60)
factorial(2,60)factorial(1,120)
factorial(1,120)factorial(0,120)
factorial(0,120)120

Memory Flow

main()

factorial(5,1)

factorial(4,5)

factorial(3,20)

factorial(2,60)

factorial(1,120)

factorial(0,120)

Return 120

Tail Recursion vs Non-Tail Recursion

FeatureTail RecursionNon-Tail Recursion
Recursive callLast statementFollowed by more operations
Work after recursive callNoYes
Compiler optimizationPossibleUsually not possible
Memory usageCan be lower if optimizedUsually higher

Tail Recursion Example

return factorial(n - 1, n * result);

No work remains after the recursive call.

Non-Tail Recursion Example

return n * factorial(n - 1);

Multiplication occurs after the recursive call returns, so it is not tail recursion.


Advantages

  • ✔ Cleaner recursive logic.
  • ✔ Can be optimized by some compilers.
  • ✔ May reduce stack usage when optimized.
  • ✔ Suitable for large recursive computations (if optimization is available).

Limitations

  • ❌ Not every recursive problem can be written as tail recursion.
  • ❌ Some C compilers do not perform tail call optimization.
  • ❌ Often requires extra parameters (accumulators), making the function slightly more complex.



📘 How to Remove Tail Recursion (Convert Tail Recursion to Iteration)

Removing tail recursion means converting a tail recursive function into an iterative (loop-based) function. Since the recursive call is the last operation, it can be easily replaced with a loop.


Steps to Remove Tail Recursion

  1. Remove the recursive function call.
  2. Replace it with a loop (while or for).
  3. Update the function parameters inside the loop.
  4. Stop the loop when the base condition is reached.

Example 1: Tail Recursive Countdown

Tail Recursive Program

#include <stdio.h>

void countdown(int n)
{
if (n == 0)
return;

printf("%d ", n);

countdown(n - 1);
}

int main()
{
countdown(5);
return 0;
}

Output

5 4 3 2 1

After Removing Tail Recursion (Using while Loop)

#include <stdio.h>

void countdown(int n)
{
while (n > 0)
{
printf("%d ", n);
n--;
}
}

int main()
{
countdown(5);
return 0;
}

Output

5 4 3 2 1

Example 2: Print Numbers from 1 to 5

Tail Recursive Version

#include <stdio.h>

void print(int n)
{
if (n > 5)
return;

printf("%d ", n);

print(n + 1);
}

int main()
{
print(1);
}

Iterative Version

#include <stdio.h>

void print(int n)
{
while (n <= 5)
{
printf("%d ", n);
n++;
}
}

int main()
{
print(1);
}

Example 3: Tail Recursive Factorial

Tail Recursive Version

#include <stdio.h>

int fact(int n, int result)
{
if (n == 0)
return result;

return fact(n - 1, n * result);
}

int main()
{
printf("%d", fact(5, 1));
}

Iterative Version

#include <stdio.h>

int fact(int n)
{
int result = 1;

while (n > 0)
{
result = result * n;
n--;
}

return result;
}

int main()
{
printf("%d", fact(5));
}

Output

120

General Method

Tail Recursive Function

function(parameter)
{
if(base condition)
return;

// Process

function(updated parameter);
}

⬇️ Convert into

Iterative Function

function(parameter)
{
while(base condition is false)
{
// Process

Update parameter;
}
}

Why Remove Tail Recursion?

  • ✅ Avoids recursive function calls.
  • ✅ Reduces memory usage (no call stack needed).
  • ✅ Prevents stack overflow.
  • ✅ Often improves performance.

Comparison

Tail RecursionIteration
Uses function callsUses loops
Uses call stackNo call stack
May consume more memoryUses less memory
Easier to write for recursive problemsOften faster

Viva Questions

  1. What is tail recursion?
  2. Why can tail recursion be converted into iteration?
  3. Which loop is commonly used to remove tail recursion?
  4. What are the advantages of removing tail recursion?
  5. Does removing tail recursion change the output of the program?





📘 Module 6: Searching, Sorting and Hashing


📖 Lecture 1: Searching and Linear Search


🎯 Learning Objectives

After completing this lecture, students will be able to:

  • Understand the concept of searching.
  • Explain Linear Search.
  • Write the Linear Search algorithm.
  • Implement Linear Search in C.
  • Analyze its time complexity.
  • Identify its advantages and disadvantages.

🔍 What is Searching?

<div style="background:#E3F2FD;padding:15px;border-left:8px solid #1976D2;border-radius:10px;">

Searching is the process of finding a specific element (key) in a collection of data such as an array, list, or database.

If the element is found, its position (index) is returned. Otherwise, the search reports that the element is not present.

</div>


🌍 Real-Life Examples

  • 📞 Searching a contact in a phone book.
  • 📚 Finding a book in a library.
  • 🎓 Searching a student's roll number.
  • 💻 Searching a file on a computer.
  • 🛒 Finding a product on an e-commerce website.

Types of Searching

Searching

├── Linear Search

└── Binary Search

What is Linear Search?

<div style="background:#FFF3E0;padding:15px;border-left:8px solid orange;border-radius:10px;">

Linear Search is the simplest searching technique. It checks each element one by one from the beginning of the array until the required element is found or the array ends.

</div>


Characteristics

  • Simple to understand and implement.
  • Searches sequentially.
  • Works with both sorted and unsorted arrays.
  • No preprocessing is required.

Algorithm for Linear Search

Step 1: Start

Step 2: Read the array, size (n), and key.

Step 3: Set i = 0.

Step 4: Compare key with A[i].

Step 5:
If A[i] == key
Display "Element Found"
Stop

Step 6:
Otherwise increment i.

Step 7:
Repeat until i = n.

Step 8:
If not found
Display "Element Not Found"

Step 9: Stop

Flowchart

            Start


Read Array & Key


i = 0


Is i < n ?
/ \
No Yes
│ │
▼ ▼
Not Found Is A[i]==Key ?
/ \
Yes No
│ │
▼ ▼
Element Found i++
│ │
└──────────┘


End

C Program

#include <stdio.h>

int main()
{
int a[100], n, key, i, found = 0;

printf("Enter number of elements: ");
scanf("%d", &n);

printf("Enter array elements:\n");

for(i = 0; i < n; i++)
scanf("%d", &a[i]);

printf("Enter element to search: ");
scanf("%d", &key);

for(i = 0; i < n; i++)
{
if(a[i] == key)
{
found = 1;
break;
}
}

if(found)
printf("Element found at position %d", i + 1);
else
printf("Element not found");

return 0;
}

Sample Input

Enter number of elements: 5

10 25 40 18 90

Enter element to search: 40

Output

Element found at position 3

Dry Run

Array:

Index : 0   1   2   3   4

Value :10 25 40 18 90

Searching for 40

StepCompared ValueResult
110Not Found
225Not Found
340Found ✅

Time Complexity

CaseComplexity
Best CaseO(1)
Average CaseO(n)
Worst CaseO(n)

Space Complexity

O(1)

Only one extra variable is used.


Advantages

<div style="background:#E8F5E9;padding:15px;border-left:8px solid green;border-radius:10px;">

  • ✔ Very easy to implement.
  • ✔ Works on both sorted and unsorted arrays.
  • ✔ No additional memory required.
  • ✔ Suitable for small datasets.

</div>


Disadvantages

<div style="background:#FFEBEE;padding:15px;border-left:8px solid red;border-radius:10px;">

  • ✘ Slow for large datasets.
  • ✘ May require checking every element.
  • ✘ Less efficient than Binary Search on sorted data.

</div>


Applications

  • Searching in small arrays.
  • Student record lookup.
  • Employee database.
  • Product search in a small inventory.
  • Contact list search.

Comparison of Search Success

Suppose the array is:

5  8  10  15  20  25

Searching for 20

5 ❌

8 ❌

10 ❌

15 ❌

20 ✅ Found

Viva Questions

  1. What is searching?
  2. Define Linear Search.
  3. Does Linear Search require a sorted array?
  4. What is the best-case time complexity of Linear Search?
  5. What is the worst-case time complexity?
  6. What is the space complexity of Linear Search?
  7. Name two applications of Linear Search.

MCQs

1. Linear Search works on:

A. Only sorted arrays
B. Only linked lists
C. Both sorted and unsorted arrays
D. Only trees


2. Worst-case complexity of Linear Search is:

A. O(1)
B. O(log n)
C. O(n)
D. O(n²)


3. Which search checks elements one by one?

A. Binary Search
B. Linear Search
C. Hash Search
D. DFS


University Exam Questions

Short Questions

  • Define Linear Search.
  • Write the algorithm of Linear Search.
  • State the advantages and disadvantages of Linear Search.

Long Questions

  • Explain Linear Search with an algorithm and C program.
  • Discuss the time complexity of Linear Search.
  • Explain the working of Linear Search with an example.

Quick Revision

TopicKey Point
SearchingFinding a specific element
Linear SearchSequential search
Works OnSorted and Unsorted Arrays
Best CaseO(1)
Worst CaseO(n)
Space ComplexityO(1)

📌 Key Takeaways

  • Linear Search examines each element one by one until the target is found or the array ends.
  • It is simple to implement and does not require the data to be sorted.
  • It is suitable for small datasets, but becomes inefficient for large datasets because its worst-case time complexity is O(n).

Lecture 2: Binary Search (BCA Notes)


🎯 Learning Objectives

After completing this lecture, students will be able to:

  • Define Binary Search.
  • Understand the working principle of Binary Search.
  • Write the Binary Search algorithm.
  • Implement Binary Search in C (Iterative and Recursive).
  • Analyze the time complexity.
  • Compare Binary Search with Linear Search.

🔍 What is Binary Search?

<div style="background:#E3F2FD;padding:15px;border-left:8px solid #1976D2;border-radius:10px;">

Binary Search is an efficient searching algorithm that works only on a sorted array. It repeatedly divides the search interval into two equal halves until the required element is found or the search interval becomes empty.

</div>


🌟 Key Idea

Instead of checking every element one by one, Binary Search compares the target element with the middle element.

  • If the key is equal to the middle element → Found
  • If the key is smaller → Search the left half
  • If the key is larger → Search the right half

📌 Prerequisite

The array must be sorted (ascending or descending order).

Example (Ascending Order):

Index : 0   1   2   3   4   5   6

Value :10 20 30 40 50 60 70

Working Principle

Suppose we want to search 50.

Step 1

10   20   30   40   50   60   70

Middle = 40

Since 50 > 40, search the right half.


Step 2

50   60   70

Middle = 60

Since 50 < 60, search the left half.


Step 3

50

Found

Algorithm (Iterative)

Step 1 : Start

Step 2 : Read the sorted array, size n, and key.

Step 3 : low = 0
high = n - 1

Step 4 : Repeat while low <= high

Step 5 : mid = (low + high) / 2

Step 6 :
If key == A[mid]
Display "Found"
Stop

Step 7 :
If key < A[mid]
high = mid - 1

Otherwise
low = mid + 1

Step 8 :
Repeat

Step 9 :
Display "Not Found"

Step 10 : Stop

Flowchart

             Start


Read Sorted Array & Key


low=0, high=n-1


low <= high ?
/ \
No Yes
│ │
▼ ▼
Not Found mid=(low+high)/2


key==A[mid]?
/ \
Yes No
│ │
▼ ▼
Element key < A[mid] ?
Found / \
Yes No
│ │
▼ ▼
high=mid-1 low=mid+1

└───────────────┐


Repeat

C Program (Iterative Binary Search)

#include <stdio.h>

int main()
{
int a[100], n, key;
int low, high, mid, i;

printf("Enter number of elements: ");
scanf("%d",&n);

printf("Enter sorted elements:\n");

for(i=0;i<n;i++)
scanf("%d",&a[i]);

printf("Enter element to search: ");
scanf("%d",&key);

low=0;
high=n-1;

while(low<=high)
{
mid=(low+high)/2;

if(a[mid]==key)
{
printf("Element Found at position %d",mid+1);
return 0;
}

else if(key<a[mid])
high=mid-1;

else
low=mid+1;
}

printf("Element Not Found");

return 0;
}

Sample Input

Enter number of elements : 7

10 20 30 40 50 60 70

Enter element : 60

Output

Element Found at position 6

Dry Run

Searching 60

Array

10 20 30 40 50 60 70

First Iteration

Low = 0

High = 6

Mid = 3

A[mid] = 40

Since 60 > 40

Search Right Half


Second Iteration

Low = 4

High = 6

Mid = 5

A[mid] = 60

Element Found.


Recursive Binary Search

Binary Search can also be implemented using recursion.


Algorithm

BinarySearch(low, high)

If low > high
return -1

mid = (low + high) / 2

If key == A[mid]
return mid

If key < A[mid]
Search left half

Otherwise
Search right half

C Program (Recursive Binary Search)

#include <stdio.h>

int binarySearch(int a[], int low, int high, int key)
{
if(low>high)
return -1;

int mid=(low+high)/2;

if(a[mid]==key)
return mid;

if(key<a[mid])
return binarySearch(a,low,mid-1,key);

return binarySearch(a,mid+1,high,key);
}

int main()
{
int a[]={10,20,30,40,50,60,70};

int n=7;

int key=30;

int result=binarySearch(a,0,n-1,key);

if(result==-1)
printf("Element Not Found");
else
printf("Element Found at position %d",result+1);

return 0;
}

Time Complexity

CaseComplexity
Best CaseO(1)
Average CaseO(log₂ n)
Worst CaseO(log₂ n)

Space Complexity

Iterative

O(1)

Recursive

O(log n)

(due to recursive function calls)


Advantages

<div style="background:#E8F5E9;padding:15px;border-left:8px solid green;border-radius:10px;">

✔ Very fast for large datasets.

✔ Reduces search space by half in every iteration.

✔ Efficient algorithm.

✔ Time complexity is O(log n).

</div>


Disadvantages

<div style="background:#FFEBEE;padding:15px;border-left:8px solid red;border-radius:10px;">

✘ Works only on sorted arrays.

✘ Sorting may require additional time.

✘ Slightly more difficult than Linear Search.

</div>


Applications

  • Dictionary word search
  • Telephone directory
  • Student record systems
  • Database indexing
  • Library management systems
  • Search engines
  • Large sorted datasets

Binary Search Visualization

Searching 70

10 20 30 40 50 60 70

40

70 > 40



50 60 70


60

70 > 60



70

Found

📊 Comparison

FeatureLinear SearchBinary Search
Working MethodSequential SearchDivide and Conquer
Array RequirementSorted or UnsortedSorted Only
Number of ComparisonsMoreFewer
Best CaseO(1)O(1)
Average CaseO(n)O(log n)
Worst CaseO(n)O(log n)
Space Complexity (Iterative)O(1)O(1)
Programming ComplexityEasyModerate
Suitable for Large DataNoYes
Suitable for Small DataYesYes
SpeedSlowerFaster


Viva Questions

  1. Define Binary Search.
  2. Why must the array be sorted?
  3. Explain the working principle of Binary Search.
  4. Write the Binary Search algorithm.
  5. What is the time complexity of Binary Search?
  6. What is the space complexity of recursive Binary Search?
  7. Differentiate iterative and recursive Binary Search.
  8. Can Binary Search work on an unsorted array? Why?


📘 Types of Sorting 

Sorting algorithms can be classified into different types based on where the data is stored, how much memory is used, and whether the relative order of equal elements is preserved.


1. Internal Sorting

<div style="background:#E3F2FD;padding:15px;border-left:8px solid #1976D2;border-radius:10px;">

Internal Sorting is a sorting technique in which all data to be sorted fits into the computer's main memory (RAM).

</div>

Characteristics

  • Entire data is available in RAM.
  • Faster than external sorting.
  • Suitable for small and medium-sized datasets.

Examples

  • Selection Sort
  • Bubble Sort
  • Insertion Sort
  • Quick Sort
  • Heap Sort
  • Merge Sort (when data fits in memory)

Applications

  • Student records
  • Employee databases
  • Small business applications

2. External Sorting

<div style="background:#FFF3E0;padding:15px;border-left:8px solid orange;border-radius:10px;">

External Sorting is used when the data is too large to fit into the main memory (RAM). The data is stored on external storage devices such as hard disks or SSDs.

</div>

Characteristics

  • Data is stored on secondary memory.
  • Slower because of disk I/O.
  • Suitable for very large datasets.

Examples

  • External Merge Sort
  • Multi-way Merge Sort

Applications

  • Database systems
  • Big Data processing
  • File systems
  • Search engines

Difference Between Internal and External Sorting

FeatureInternal SortingExternal Sorting
Memory UsedMain Memory (RAM)Secondary Storage (Disk)
Data SizeSmall or MediumVery Large
SpeedFasterSlower
CostLowHigher
ExamplesBubble, Selection, InsertionExternal Merge Sort

3. In-Place Sorting

An In-Place Sorting algorithm sorts the data without requiring significant extra memory. It uses only a constant amount of additional space.

Space Complexity

O(1)

Characteristics

  • Uses very little extra memory.
  • Memory-efficient.
  • Modifies the original array directly.

Examples

  • Selection Sort
  • Bubble Sort
  • Insertion Sort
  • Heap Sort
  • Quick Sort (uses only a small recursion stack)

4. Out-of-Place Sorting

An Out-of-Place Sorting algorithm requires additional memory to sort the elements.

Characteristics

  • Creates another array or uses extra storage.
  • Requires more memory.
  • Often easier to implement.

Examples

  • Merge Sort
  • Counting Sort
  • Radix Sort

Difference Between In-Place and Out-of-Place Sorting

FeatureIn-PlaceOut-of-Place
Extra MemoryVery Small (O(1))Additional Memory Required
Original ArrayModified DirectlyNew Array Used
Memory EfficientYesNo
ExamplesBubble, Selection, InsertionMerge Sort, Counting Sort

5. Stable Sorting

<div style="background:#E8F5E9;padding:15px;border-left:8px solid #4CAF50;border-radius:10px;">

A Stable Sorting algorithm preserves the relative order of equal elements after sorting.

</div>

Example

Before Sorting

Roll   Name    Marks

101 Rahul 80
102 Priya 90
103 Amit 80

After Stable Sorting by Marks

102    Priya    90
101 Rahul 80
103 Amit 80

Notice that Rahul remains before Amit because both have the same marks.

Examples

  • Bubble Sort
  • Insertion Sort
  • Merge Sort
  • Counting Sort

6. Unstable Sorting

<div style="background:#FFEBEE;padding:15px;border-left:8px solid red;border-radius:10px;">

An Unstable Sorting algorithm does not preserve the relative order of equal elements.

</div>

Example

Before Sorting

101 Rahul 80

102 Priya 90

103 Amit 80

Possible Result After Sorting

102 Priya 90

103 Amit 80

101 Rahul 80

The order of Rahul and Amit has changed.

Examples

  • Selection Sort
  • Quick Sort
  • Heap Sort

Classification of Common Sorting Algorithms

Sorting AlgorithmInternalExternalIn-PlaceStable
Bubble Sort
Selection Sort
Insertion Sort
Merge Sort✅*
Quick Sort
Heap Sort
Counting Sort
Radix Sort

Note: Merge Sort can be used as an external sorting algorithm when adapted for data stored on disk.


Memory Diagram

                 Sorting

┌───────────────┴───────────────┐
│ │
Internal Sorting External Sorting
│ │
Data in RAM Data on Disk

Another Classification

                    Sorting

┌───────────────┴───────────────┐
│ │
In-Place Out-of-Place
│ │
O(1) Extra Space Extra Memory Needed

Viva Questions

  1. What is Internal Sorting?
  2. What is External Sorting?
  3. Define In-Place Sorting.
  4. Define Out-of-Place Sorting.
  5. What is Stable Sorting?
  6. What is Unstable Sorting?
  7. Which sorting algorithms are stable?
  8. Which sorting algorithms are in-place?
  9. Which sorting algorithm is commonly used for external sorting?
  10. Differentiate Internal and External Sorting.

Quick Revision

TypeKey Point
Internal SortingData fits in RAM
External SortingData stored on disk
In-Place SortingUses O(1) extra memory
Out-of-Place SortingRequires extra memory
Stable SortingPreserves order of equal elements
Unstable SortingMay change the order of equal elements

🎓 Exam Tip

Remember these common examples:

CategoryExamples
Internal SortingBubble, Selection, Insertion, Quick, Heap
External SortingExternal Merge Sort
In-Place SortingBubble, Selection, Insertion, Heap, Quick
Out-of-Place SortingMerge Sort, Counting Sort, Radix Sort
Stable SortingBubble, Insertion, Merge, Counting
Unstable SortingSelection, Quick, Heap


📘 Selection Sort 


🔷 Definition

Selection Sort is a simple comparison-based sorting algorithm. It repeatedly selects the smallest element from the unsorted portion of the array and places it at the beginning. This process continues until the entire array is sorted.


🔷 Algorithm of Selection Sort

Algorithm: Selection Sort

Step 1: Start

Step 2: Read the array and its size (n).

Step 3: Repeat for i = 0 to n - 2

a. Assume the first unsorted element is the minimum.
min = i

b. Compare a[min] with all remaining elements.

c. If a smaller element is found,
min = j

d. Swap a[i] and a[min].

Step 4: Repeat until the array is sorted.

Step 5: Stop.

🔷 Flow of Selection Sort

Start



Read Array



Find Smallest Element



Swap with First Unsorted Element



Repeat for Remaining Elements



Sorted Array



Stop

🔷 C++ Program for Selection Sort

#include <iostream>
using namespace std;

int main()
{
int a[100], n, i, j, minIndex, temp;

cout << "Enter number of elements: ";
cin >> n;

cout << "Enter array elements:\n";

for(i = 0; i < n; i++)
cin >> a[i];

// Selection Sort
for(i = 0; i < n - 1; i++)
{
minIndex = i;

for(j = i + 1; j < n; j++)
{
if(a[j] < a[minIndex])
minIndex = j;
}

// Swap
temp = a[i];
a[i] = a[minIndex];
a[minIndex] = temp;
}

cout << "\nSorted Array:\n";

for(i = 0; i < n; i++)
cout << a[i] << " ";

return 0;
}

🔷 Sample Input

Enter number of elements: 5

64 25 12 22 11

🔷 Output

Sorted Array:

11 12 22 25 64

🔷 Pass-wise Example

Initial Array

64 25 12 22 11

Pass 1

Smallest element = 11

Swap with first element.

11 25 12 22 64

Pass 2

Unsorted Part

25 12 22 64

Smallest = 12

11 12 25 22 64

Pass 3

Unsorted Part

25 22 64

Smallest = 22

11 12 22 25 64

Pass 4

Unsorted Part

25 64

Already sorted.

11 12 22 25 64

🔷 Total Comparisons

For n elements,

(n1)+(n2)++2+1=n(n1)2(n-1)+(n-2)+\cdots+2+1=\frac{n(n-1)}{2}

For 5 elements:

4 + 3 + 2 + 1 = 10 comparisons

🔷 Time Complexity

CaseTime Complexity
Best CaseO(n²)
Average CaseO(n²)
Worst CaseO(n²)

Explanation

  • Best Case: Even if the array is already sorted, Selection Sort still scans the remaining elements to find the minimum.
  • Average Case: Every element is compared with the remaining unsorted elements.
  • Worst Case: The number of comparisons remains the same as in the best and average cases.

Therefore, the time complexity is O(n²) in all cases.


🔷 Space Complexity

TypeComplexity
Auxiliary SpaceO(1)

Explanation

Selection Sort is an in-place sorting algorithm. It uses only a few extra variables (minIndex and temp) regardless of the input size.

Hence, the space complexity is:

O(1)

🔷 Advantages

  • ✔ Easy to understand and implement.
  • ✔ Requires only O(1) extra memory.
  • ✔ Performs fewer swaps than Bubble Sort.
  • ✔ Suitable for small datasets.

🔷 Disadvantages

  • ✘ Inefficient for large datasets.
  • ✘ Time complexity is always O(n²).
  • ✘ Not a stable sorting algorithm.
  • ✘ Does not adapt to already sorted data.

🔷 Applications

  • Sorting small arrays.
  • Educational purposes.
  • Memory-constrained systems.
  • Situations where minimizing the number of swaps is important.

🔷 Viva Questions

  1. What is Selection Sort?
  2. Why is it called Selection Sort?
  3. How many passes are required for n elements?
  4. What is the best-case time complexity of Selection Sort?
  5. Is Selection Sort a stable sorting algorithm?
  6. What is the space complexity of Selection Sort?
  7. Is Selection Sort an in-place sorting algorithm?



Bubble Sort

📘 Definition

Bubble Sort is a simple comparison-based sorting algorithm in which adjacent elements are repeatedly compared and swapped if they are in the wrong order. After each pass, the largest unsorted element moves (or "bubbles") to its correct position at the end of the array. This process continues until the entire array is sorted.


📝 Algorithm

Algorithm BubbleSort(A, n)

Step 1: Repeat for i = 0 to n − 2
Step 2: Repeat for j = 0 to n − i − 2
Step 3: If A[j] > A[j + 1]
Step 4: Swap A[j] and A[j + 1]
Step 5: End If
Step 6: End For
Step 7: End For
Step 8: Stop

💻 C++ Program

#include <iostream>
using namespace std;

int main()
{
int A[] = {64, 34, 25, 12, 22, 11};
int n = 6;

for(int i = 0; i < n - 1; i++)
{
for(int j = 0; j < n - i - 1; j++)
{
if(A[j] > A[j + 1])
{
int temp = A[j];
A[j] = A[j + 1];
A[j + 1] = temp;
}
}
}

cout << "Sorted Array: ";

for(int i = 0; i < n; i++)
cout << A[i] << " ";

return 0;
}

📊 Example

Initial Array

64   34   25   12   22   11

Pass 1

64 34 → Swap
34 64 25 12 22 11

64 25 → Swap
34 25 64 12 22 11

64 12 → Swap
34 25 12 64 22 11

64 22 → Swap
34 25 12 22 64 11

64 11 → Swap
34 25 12 22 11 64

Largest element 64 reaches its correct position.


Pass 2

34 25 → Swap
25 34 12 22 11 64

34 12 → Swap
25 12 34 22 11 64

34 22 → Swap
25 12 22 34 11 64

34 11 → Swap
25 12 22 11 34 64

Pass 3

25 12 → Swap
12 25 22 11 34 64

25 22 → Swap
12 22 25 11 34 64

25 11 → Swap
12 22 11 25 34 64

Pass 4

12 22 → No Swap

22 11 → Swap

12 11 22 25 34 64

Pass 5

12 11 → Swap

11 12 22 25 34 64

✅ Sorted Array

11   12   22   25   34   64

📈 Number of Comparisons (6 Elements)

PassComparisons
Pass 15
Pass 24
Pass 33
Pass 42
Pass 51
Total15

Formula

(n1)+(n2)++2+1=n(n1)2(n-1)+(n-2)+\cdots+2+1 = \frac{n(n-1)}{2}

For 6 elements

6(61)2=15\frac{6(6-1)}{2} = 15


🔄 Number of Swaps (Worst Case)

For a reverse sorted array:

64 34 25 22 12 11

Maximum swaps

n(n1)2=15\frac{n(n-1)}{2} = 15


⏱️ Time Complexity

CaseComplexity
Best Case (Optimized Bubble Sort)O(n)
Average CaseO(n²)
Worst CaseO(n²)

💾 Space Complexity

O(1)

Only one temporary variable is used for swapping.


⭐ Characteristics of Bubble Sort

PropertyValue
Sorting MethodComparison Based
Stable✔ Yes
In-place✔ Yes
Adaptive✔ Yes (Optimized Version)
Recursive❌ No
Online❌ No


Insertion Sort


📘 Definition

Insertion Sort is a simple comparison-based sorting algorithm that builds the sorted array one element at a time. It takes each element from the unsorted portion and inserts it into its correct position in the sorted portion of the array. It is similar to the way people arrange playing cards in their hands.


📝 Algorithm

Algorithm InsertionSort(A, n)

Step 1: Repeat for i = 1 to n − 1
Step 2: key = A[i]
Step 3: j = i − 1
Step 4: While (j ≥ 0) and (A[j] > key)
Step 5: A[j + 1] = A[j]
Step 6: j = j − 1
Step 7: End While
Step 8: A[j + 1] = key
Step 9: End For
Step 10: Stop

💻 C++ Program

#include <iostream>
using namespace std;

int main()
{
int A[] = {64, 34, 25, 12, 22, 11};
int n = 6;

for(int i = 1; i < n; i++)
{
int key = A[i];
int j = i - 1;

while(j >= 0 && A[j] > key)
{
A[j + 1] = A[j];
j--;
}

A[j + 1] = key;
}

cout << "Sorted Array: ";

for(int i = 0; i < n; i++)
cout << A[i] << " ";

return 0;
}

📊 Example

Initial Array

64   34   25   12   22   11

Pass 1 (Key = 34)

64 > 34

Shift 64 to right

34 64 25 12 22 11

Pass 2 (Key = 25)

64 > 25  → Shift

34 > 25 → Shift

25 34 64 12 22 11

Pass 3 (Key = 12)

64 > 12 → Shift

34 > 12 → Shift

25 > 12 → Shift

12 25 34 64 22 11

Pass 4 (Key = 22)

64 > 22 → Shift

34 > 22 → Shift

25 > 22 → Shift

12 < 22 → Stop

12 22 25 34 64 11

Pass 5 (Key = 11)

64 > 11 → Shift

34 > 11 → Shift

25 > 11 → Shift

22 > 11 → Shift

12 > 11 → Shift

11 12 22 25 34 64

✅ Sorted Array

11   12   22   25   34   64

📈 Number of Comparisons (Worst Case – 6 Elements)

PassComparisons
Pass 11
Pass 22
Pass 33
Pass 44
Pass 55
Total15

Formula

1+2+3++(n1)=n(n1)21+2+3+\cdots+(n-1)=\frac{n(n-1)}{2}

For 6 elements

6(61)2=15\frac{6(6-1)}{2} = 15


📦 Number of Shifts (Worst Case)

Worst-case input:

64   34   25   22   12   11
PassShifts
Pass 11
Pass 22
Pass 33
Pass 44
Pass 55
Total15

⏱️ Time Complexity

CaseComplexity
Best Case (Already Sorted)O(n)
Average CaseO(n²)
Worst Case (Reverse Sorted)O(n²)

💾 Space Complexity

O(1)

Insertion Sort uses only one extra variable (key), so it requires constant extra memory.


⭐ Characteristics of Insertion Sort

PropertyValue
Sorting MethodComparison Based
Stable✔ Yes
In-place✔ Yes
Adaptive✔ Yes
Recursive❌ No
Online✔ Yes


📊 Comparison of Sorting Techniques

The following table compares the three basic sorting algorithms commonly studied in BCA/B.Sc. Computer Science.

FeatureBubble SortSelection SortInsertion Sort
Sorting MethodCompares adjacent elements and swaps themSelects the minimum element and places it in the correct positionInserts each element into its correct position in the sorted part
Best Case Time ComplexityO(n) (Optimized)O(n²)O(n)
Average Case Time ComplexityO(n²)O(n²)O(n²)
Worst Case Time ComplexityO(n²)O(n²)O(n²)
Space ComplexityO(1)O(1)O(1)
Stable✔ Yes❌ No✔ Yes
Adaptive✔ Yes (Optimized)❌ No✔ Yes
In-place✔ Yes✔ Yes✔ Yes
Online Algorithm❌ No❌ No✔ Yes
Maximum Comparisonsn(n−1)/2n(n−1)/2n(n−1)/2
Maximum Swaps/Shiftsn(n−1)/2 swapsn−1 swapsn(n−1)/2 shifts
Best Suitable ForSmall datasetsWhen minimizing swaps is importantSmall or nearly sorted datasets
EfficiencyLowBetter than Bubble (fewer swaps)Better for nearly sorted data

⭐ Advantages Comparison

Bubble SortSelection SortInsertion Sort
Easy to understandPerforms minimum swapsVery efficient for nearly sorted data
Stable sortingSimple implementationStable sorting
Adaptive (optimized version)Uses constant memoryAdaptive and Online
Good for educational purposesGood when swap operations are expensiveExcellent for small datasets

❌ Disadvantages Comparison

Bubble SortSelection SortInsertion Sort
Too many swapsNot stableToo many shifts in worst case
Slow for large datasetsNot adaptiveSlow for large datasets
Inefficient for large dataAlways performs the same number of comparisonsPerformance decreases for reverse-sorted data

Hashing


📘 Definition

Hashing is a technique used to store and retrieve data quickly. It converts a key into a small integer called a hash value (hash code) using a hash function. The hash value determines the location (index) where the data is stored in a hash table.

The main advantage of hashing is that it allows fast searching, insertion, and deletion of data.

📚 Key Terms

1. Key

A key is the value used to identify a record.

Example:

Student Roll Number = 105
Employee ID = 2001

2. Hash Function

A hash function is a mathematical formula that converts a key into an index of the hash table.

One of the most common hash functions is:

Hash Index=KeymodTable Size\boxed{\text{Hash Index} = \text{Key} \bmod \text{Table Size}}

3. Hash Table

A Hash Table is an array in which records are stored according to their hash values.

Example (Table Size = 10)

IndexData
0
121
232
3
454
515
6
7
8
929

🔢 Example of Hashing

Suppose,

Keys

25, 42, 33, 56, 71

Hash Table Size = 10

Hash Function

H(Key) = Key % 10

Step 1

25 % 10 = 5

Store at Index 5


Step 2

42 % 10 = 2

Store at Index 2


Step 3

33 % 10 = 3

Store at Index 3


Step 4

56 % 10 = 6

Store at Index 6


Step 5

71 % 10 = 1

Store at Index 1


Final Hash Table

IndexData
0
171
242
333
4
525
656
7
8
9



Different Types of Hash Functions

A hash function is a mathematical function that converts a key into an index (hash value) in a hash table. A good hash function distributes keys uniformly to minimize collisions.


1. Division (Remainder) Method

Definition

The Division Method is the simplest and most commonly used hash function. The hash value is obtained by dividing the key by the table size and taking the remainder.

Formula

H(k)=kmodmH(k) = k \bmod m

Where:

  • k = Key
  • m = Size of the hash table

Example 1

Key = 25
Table Size = 10

H(25) = 25 % 10 = 5

Store 25 at Index 5.


Example 2

Key = 42
Table Size = 10

H(42) = 42 % 10 = 2

Store 42 at Index 2.


Example 3

Key = 87
Table Size = 10

H(87) = 87 % 10 = 7

Store 87 at Index 7.


Advantages

  • Very easy to implement.
  • Fast computation.
  • Most widely used in practice.

2. Mid-Square Method

Definition

In the Mid-Square Method, the key is squared, and the middle digit(s) of the square are selected as the hash value.

Steps

  1. Square the key.
  2. Extract the middle digit(s).
  3. Use the extracted digit(s) as the hash value.

Example 1

Key = 25

25² = 625

Middle digit = 2

Hash Value = 2

Example 2

Key = 36

36² = 1296

Middle digits = 29

Hash Value = 29

Example 3

Key = 48

48² = 2304

Middle digits = 30

Hash Value = 30

Advantages

  • Better distribution of keys than the Division Method.
  • Reduces clustering.

3. Folding Method

Definition

In the Folding Method, the key is divided into equal-sized parts, and these parts are added together. The final result (or its remainder) becomes the hash value.

Steps

  1. Divide the key into equal parts.
  2. Add the parts.
  3. If necessary, apply the modulo operation.

Example 1

Key = 123456

Divide:

123 + 456 = 579

Hash Value = 579 % 100 = 79

Example 2

Key = 987654

Divide:

987 + 654 = 1641

Hash Value = 1641 % 100 = 41

Example 3

Key = 456789

Divide:

456 + 789 = 1245

Hash Value = 1245 % 100 = 45

Advantages

  • Suitable for long numeric keys.
  • Provides better key distribution than simple modulo in many cases.


  • Collision Resolution

    Definition

    Collision Resolution is the process of handling collisions so that all keys can be stored and retrieved correctly from the hash table.

    There are several collision resolution techniques.


    1. Linear Probing (Open Addressing)

    Definition

    If the calculated index is already occupied, check the next available location until an empty slot is found.

    Formula

    Hi(k)=(H(k)+i)modmH_i(k)=(H(k)+i)\bmod m

    where:

    • H(k) = original hash value
    • i = 0, 1, 2, ...
    • m = table size

    Example

    Keys:

    25, 35, 45

    Hash Function:

    H(k)=k%10

    Insertion

    25 → Index 5

    35 → Index 5 occupied → Store at Index 6

    45 → Index 5 occupied
    Index 6 occupied
    Store at Index 7

    Hash Table

    IndexData
    0
    1
    2
    3
    4
    525
    635
    745
    8
    9

    Advantages

    • Easy to implement.
    • No extra memory required.

    Disadvantages

    • Causes primary clustering.
    • Search time increases as the table fills.

    2. Quadratic Probing

    Definition

    Instead of checking consecutive locations, the next position is calculated using square numbers.

    Formula

    Hi(k)=(H(k)+i2)modmH_i(k)=\left(H(k)+i^2\right)\bmod m

    Example

    Keys:

    25, 35, 45

    Hash Function:

    H(k)=k%10

    Insertion:

    25 → Index 5

    35 → 5 + 1² = 6

    45 → 5 + 2² = 9

    Hash Table

    IndexData
    525
    635
    945

    Advantages

    • Reduces primary clustering.
    • Better distribution than linear probing.

    Disadvantages

    • More complex than linear probing.
    • May not find an empty slot unless the table is designed properly.

    3. Double Hashing

    Definition

    Uses two different hash functions. The second hash function determines the step size for probing.

    Formula

    Hi(k)=(H1(k)+i×H2(k))modmH_i(k)=\left(H_1(k)+i\times H_2(k)\right)\bmod m

    Example

    Let:

    H1(k)=k%10

    H2(k)=7-(k%7)

    For key 35:

    H1(35)=5

    H2(35)=7-(35%7)=7

    Next Index=(5+1×7)%10=2

    So, 35 is stored at Index 2.


    Advantages

    • Best distribution among open addressing methods.
    • Minimizes clustering.

    Disadvantages

    • Requires two hash functions.
    • More complex to implement.

    4. Separate Chaining

    Definition

    Each index of the hash table stores a linked list (or another dynamic data structure). All keys that hash to the same index are stored in that list.


    Example

    Keys:

    25, 35, 45

    All hash to Index 5.

    Hash Table

    Index 5

    25 → 35 → 45 → NULL

    Advantages

    • Simple and effective.
    • Handles many collisions efficiently.
    • Table can store more elements than its size.

    Disadvantages

    • Requires extra memory for linked lists.
    • Slightly slower due to pointer traversal.

    Comparison of Collision Resolution Techniques

    TechniqueMethodExtra MemoryClusteringEasy to Implement
    Linear ProbingNext free slot❌ NoHigh✔ Yes
    Quadratic ProbingSquare increments❌ NoLowModerate
    Double HashingSecond hash function❌ NoVery LowModerate
    Separate ChainingLinked list at each index✔ YesNone✔ Yes

    Time Complexity

    OperationAverage CaseWorst Case
    SearchO(1)O(n)
    InsertO(1)O(n)
    DeleteO(1)O(n)
  • ------------------------------------------



📘 Definition

Double Hashing is a collision resolution technique used in hashing. When a collision occurs, instead of checking the next position sequentially (as in Linear Probing), Double Hashing uses a second hash function to calculate the next index. This reduces clustering and distributes keys more uniformly across the hash table.


Why is it Called "Double Hashing"?

It uses two hash functions:

  1. Primary Hash Function – Finds the initial index.
  2. Secondary Hash Function – Determines the step size for finding the next available position.

Formula

Primary Hash Function:

H1(k)=kmodmH_1(k)=k \bmod m

Secondary Hash Function:

H2(k)=R(kmodR)H_2(k)=R-(k \bmod R)

where:

  • k = Key
  • m = Size of the hash table
  • R = A prime number smaller than m

Final Probe Formula:

H(k,i)=(H1(k)+i×H2(k))modmH(k,i)=\left(H_1(k)+i \times H_2(k)\right)\bmod m

where:

  • i = 0, 1, 2, 3, ...

Example

Given

Hash Table Size (m) = 10

Primary Hash Function:
H1(k) = k % 10

Secondary Hash Function:
H2(k) = 7 - (k % 7)

Keys:
25, 35, 45

Step 1: Insert 25

H1(25) = 25 % 10 = 5

Store 25 at Index 5.

IndexData
525

Step 2: Insert 35

Primary Hash

H1(35) = 35 % 10 = 5

Index 5 is already occupied.

Secondary Hash

H2(35) = 7 - (35 % 7)
= 7 - 0
= 7

Now calculate the new index.

For i = 1

New Index

= (5 + 1 × 7) % 10

= 12 % 10

= 2

Store 35 at Index 2.

IndexData
235
525

Step 3: Insert 45

Primary Hash

H1(45) = 45 % 10 = 5

Collision occurs again.

Secondary Hash

H2(45)

= 7 - (45 % 7)

= 7 - 3

= 4

For i = 1

New Index

= (5 + 1 × 4) % 10

= 9

Store 45 at Index 9.


Final Hash Table

IndexData
0
1
235
3
4
525
6
7
8
945

Working Diagram

Keys

25 ─────► Index 5

35 ─► Collision at 5


Second Hash Function


Index 2

45 ─► Collision at 5


Second Hash Function


Index 9

Advantages

  • Reduces primary clustering and secondary clustering.
  • Provides a more uniform distribution of keys.
  • Better performance than Linear Probing and Quadratic Probing.
  • Improves search efficiency.

Disadvantages

  • Requires two hash functions.
  • More difficult to implement.
  • A good secondary hash function is essential.

Time Complexity

OperationAverage CaseWorst Case
SearchO(1)O(n)
InsertO(1)O(n)
DeleteO(1)O(n)

Comparison with Other Collision Resolution Techniques

Technique        Probe SequenceClustering
Linear Probing   +1, +2, +3, ...High
Quadratic Probing   +1², +2², +3², ...Moderate
Double HashingUses a second hash functionVery Low