Back to Main ACS Page

Module 3: Searching

Master the fundamentals of searching algorithms. Learn how to implement and analyze searching algorithms.

Module Objectives

Upon completion of this module you will be able to:

Linear Search

Understanding Linear Search

Linear search is the simplest search algorithm. It sequentially checks each element in a collection until the target is found or the collection is exhausted.

# Linear search implementation def linear_search(arr, target): for i, value in enumerate(arr): if value == target: return i # Return the index where target is found return -1 # Return -1 if target is not found # Example usage numbers = [10, 24, 56, 7, 89, 42, 13] print(linear_search(numbers, 89)) # 4 print(linear_search(numbers, 100)) # -1

Time Complexity:

Space Complexity: O(1) - Uses a constant amount of extra space

Advantages of Linear Search:

Disadvantages:

Optimized Linear Search

We can optimize linear search by adding early termination conditions or implementing search strategies like the sentinel search:

# Linear search with sentinel def sentinel_linear_search(arr, target): n = len(arr) last = arr[-1] arr[-1] = target i = 0 while arr[i] != target: i += 1 arr[-1] = last if i < n - 1 or last==target: return i return -1

Binary Search

Understanding Binary Search

Binary search is a divide-and-conquer algorithm that efficiently finds a target value in a sorted array. It repeatedly divides the search space in half, eliminating half of the remaining elements at each step.

# Binary search implementation (iterative) def binary_search(arr, target): left = 0 right = len(arr) - 1 while left <= right: mid=left + (right - left) // 2 if arr[mid]==target: return mid if arr[mid] < target: left=mid + 1 else: right=mid - 1 return -1 # Example usage sorted_numbers=[2, 5, 8, 12, 16, 23, 38, 56, 72, 91] print(binary_search(sorted_numbers, 23)) # 5 print(binary_search(sorted_numbers, 25)) # -1

Recursive Binary Search

Binary search can also be implemented recursively:

# Binary search implementation (recursive) def binary_search_recursive(arr, target, left=0, right=None): if right is None: right = len(arr) - 1 # Base case: element not found if left > right: return -1 # Calculate middle index mid = left + (right - left) // 2 # Check if target is at mid if arr[mid] == target: return mid # Recursive cases if arr[mid] < target: # Search right half return binary_search_recursive(arr, target, mid + 1, right) else: # Search left half return binary_search_recursive(arr, target, left, mid - 1)

Time Complexity:

Space Complexity:

Advantages of Binary Search:

Disadvantages:

Comparison: Linear vs. Binary Search

Aspect Linear Search Binary Search
Time Complexity O(n) O(log n)
Data Requirement Works on sorted or unsorted data Requires sorted data
Best For Small datasets, unsorted data Large datasets, sorted data
Implementation Simple More complex
Data Structure Works with arrays and linked lists Requires random access (arrays)

Practical Example: Searching in a phonebook

For a phonebook with 1000 pages:

Practice with LeetCode Problems

Note: Previously, this course referenced the CodeSignal Arcade for practice, which is no longer available. The LeetCode problems below follow the same principles and are an excellent alternative for practicing search algorithms.

Linear Search Problems:

Binary Search Problems: