Introduction
Searching algorithms are important and fundamental to data structures and computer science in general, enabling efficient data retrieval from different data structures. In C#, these algorithms are used for tasks ranging from simple lookups to complex data processing applications. In simple terms, a search algorithm is a set of procedures used to locate a specific item within a collection of items.
In this article, we are going to learn how to implement the ten most common searching algorithms in C# as well as how to reduce their complexities.
1. Linear Search
- Description: A simple algorithm that checks each element in a list sequentially until the target is found or the list comes to an end.
- Use Case: Good for unsorted or small data sets.
How Does It Work?
This algorithm checks each element in the array sequentially. It starts from the first element and compares it with the target value. If it finds a match, it returns the index; if it reaches the end without finding the target, it returns -1, which means the target is not found.
Complexity: O(n), where n is the number of elements in the array.
Example
using System;
class LinearSearchExample
{
static int LinearSearch(int[] arr, int target)
{
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] == target)
return i; // Found
}
return -1; // Not found
}
static void Main()
{
int[] numbers = { 13, 5, 6, 8, 2, 15 };
int target = 8;
int result = LinearSearch(numbers, target);
Console.WriteLine(result != -1 ? $"The target found at index: {result}" : "Not found");
}
}

2. Binary Search
- Description: An efficient algorithm that divides a sorted list in half repeatedly until the target is found.
- Use Case: This can be applied only to sorted arrays or lists.
How Does It Work?
This algorithm requires the array or list to be sorted. It finds the middle element first and compares it to the target. If the middle element is equal to the target, it returns the index. If the target is less, it recursively searches the left half; if greater, then the right half, and so on, until it finds the target or the halves come to an end.
Complexity: O(log n)
Example
using System;
class BinarySearchExample
{
static int BinarySearch(int[] arr, int target)
{
int left = 0, right = arr.Length - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == target)
return mid;
if (arr[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
return -1; // Not found
}
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int target = 7;
int result = BinarySearch(numbers, target);
Console.WriteLine(result != -1 ? $"Target was found at index: {result}" : "Not found");
}
}

3. Jump Search
- Description: A search algorithm that jumps ahead by fixed steps (or blocks) and then performs a linear search within the block.
- Use Case: Useful for sorted arrays where the size is already known.
How Does It Work?
This algorithm divides the array into blocks of size √n. It jumps ahead by block size until it finds a block where the target could exist, then performs a linear search within that block.
Complexity: O(√n)
Example
using System;
class JumpSearchExample
{
static int JumpSearch(int[] arr, int target)
{
int n = arr.Length;
int step = (int)Math.Floor(Math.Sqrt(n));
int prev = 0;
while (arr[Math.Min(step, n) - 1] < target)
{
prev = step;
step += (int)Math.Floor(Math.Sqrt(n));
if (prev >= n) return -1;
}
while (arr[prev] < target)
{
prev++;
if (prev == Math.Min(step, n)) return -1;
}
return arr[prev] == target ? prev : -1;
}
static void Main()
{
int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int target = 3;
int result = JumpSearch(numbers, target);
Console.WriteLine(result != -1 ? $"The target was found at index: {result}" : "Not found");
}
}

4. Exponential Search
- Description: Combines binary search and exponential search algorithms techniques to find the range of the target and then does a binary search.
- Use Case: Efficient for unbounded or infinite lists.
How Does It Work?
This algorithm first finds the range where the target might be located by doubling the index (1, 2, 4, etc.) until the target is less than the current value. It then does a binary search in that range.
Complexity: O(log n)
Example
using System;
class ExponentialSearchExample
{
static int BinarySearch(int[] arr, int left, int right, int target)
{
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
static int ExponentialSearch(int[] arr, int target)
{
if (arr[0] == target) return 0;
int i = 1;
while (i < arr.Length && arr[i] <= target) i *= 2;
return BinarySearch(arr, i / 2, Math.Min(i, arr.Length - 1), target);
}
static void Main()
{
int[] numbers = { 2, 3, 4, 10, 40, 50, 60, 70, 80, 90, 100 };
int target = 60;
int result = ExponentialSearch(numbers, target);
Console.WriteLine(result != -1 ? $"Found at index: {result}" : "Not found");
}
}

5. Interpolation Search
- Description: An improvement to the binary search algorithm that estimates the position of the target based on the value of the target.
- Use Case: Works well for uniformly distributed sorted data.
How Does It Work?
This algorithm estimates the position of the target based on its value relative to the elements at the ends of the current range. If the target is found, it returns the index; otherwise, it reduces the search range.
Complexity: O(log log n) on average, but can degrade to O(n) in the worst case.
Example
using System;
class InterpolationSearchExample
{
static int InterpolationSearch(int[] arr, int target)
{
int low = 0, high = arr.Length - 1;
while (low <= high && target >= arr[low] && target <= arr[high])
{
if (low == high)
{
if (arr[low] == target) return low;
return -1;
}
int pos = low + ((target - arr[low]) * (high - low)) / (arr[high] - arr[low]);
if (arr[pos] == target) return pos;
if (arr[pos] < target) low = pos + 1;
else high = pos - 1;
}
return -1;
}
static void Main()
{
int[] numbers = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
int target = 50;
int result = InterpolationSearch(numbers, target);
Console.WriteLine(result != -1 ? $"Target found at index: {result}" : "Not found");
}
}

6. Fibonacci Search
- Description: A search algorithm that uses Fibonacci numbers to divide the array into sections.
- Use Case: Effective for sorted arrays, especially when the size is Fibonacci-like.
How Does It Work?
Similar to binary search, it uses Fibonacci numbers to divide the array into sections. It calculates two midpoints based on Fibonacci numbers and reduces the search area accordingly.
Complexity: O(log n)
Example





Join the conversation! Your thoughts help the community grow.