Swift Program to Implement Exponential Search

Swift Program to Implement Exponential Search

Exponential Search is a powerful searching technique that combines the speed of doubling steps with the precision of Binary Search. It is designed for sorted arrays and works by jumping through the data in growing steps until it finds a range where the target might be. Once that range is discovered, it hands the job over to Binary Search to finish the search quickly. This makes the algorithm especially useful when the target is expected to appear near the beginning of the list or when the size of the data grows very large.

Pluralsight Logo
Accelerate your tech career
with hands-on learning.
Whether you're a tech newbie or a total pro,
get the skills and confidence to land your next move.
Start 10-Day Free Trial

Many Swift beginners enjoy learning Exponential Search because it gives a new way to think about efficiency. It doesn’t inspect every element from the start, and it also doesn’t jump blindly. Instead, it uses a controlled pattern of doubling the search range to quickly narrow down where the element could be. This balance of exploration and precision shows how good algorithm design can save time and reduce unnecessary work. Whether you’re learning Swift for interviews, school, or personal improvement, Exponential Search is a great tool to add to your collection.

Program 1: Basic Exponential Search with Built-In Binary Search

This first program shows the standard approach to Exponential Search in Swift. It finds a search range by doubling the index, then applies Binary Search to finish the job.

import Foundation

func exponentialSearch(_ array: [Int], target: Int) -> Int? {

    if array.isEmpty {
        return nil
    }

    if array[0] == target {
        return 0
    }

    var bound = 1

    while bound < array.count && array[bound] <= target {
        bound *= 2
    }

    let left = bound / 2
    let right = min(bound, array.count - 1)

    return binarySearch(array, target: target, left: left, right: right)

}

func binarySearch(_ array: [Int], target: Int, left: Int, right: Int) -> Int? {

    var low = left
    var high = right

    while low <= high {

        let mid = low + (high - low) / 2

        if array[mid] == target {
            return mid
        } else if target < array[mid] {
            high = mid - 1
        } else {
            low = mid + 1
        }

    }

    return nil

}

let data = [2, 5, 8, 14, 19, 27, 34, 41]

if let index = exponentialSearch(data, target: 19) {
    print("Found at index \(index)")
} else {
    print("Not found")
}

This version works by detecting the correct search range in a fast, doubling pattern. When the range is found, a simple Binary Search takes over. It is useful for beginners because it shows how two algorithms can work together, each doing the part it is best at.

Program 2: Pure Iterative Exponential Search

This second program performs the exponential phase and the binary search entirely in iterative form. Some learners prefer this because it avoids recursion completely.

import Foundation

func exponentialSearchIterative(_ array: [Int], target: Int) -> Int? {

    if array.isEmpty {
        return nil
    }

    if array[0] == target {
        return 0
    }

    var bound = 1

    while bound < array.count && array[bound] <= target {
        bound *= 2
    }

    var left = bound / 2
    var right = min(bound, array.count - 1)

    while left <= right {

        let mid = left + (right - left) / 2

        if array[mid] == target {
            return mid
        }

        if target < array[mid] {
            right = mid - 1
        } else {
            left = mid + 1
        }

    }

    return nil

}

let numbers = [3, 9, 12, 18, 25, 33, 42]

if let index = exponentialSearchIterative(numbers, target: 33) {
    print("Found at index \(index)")
} else {
    print("Not found")
}

This version keeps everything inside a single function. Beginners often find this helpful because the flow stays in one place, making it easier to track the variable changes as the algorithm narrows the search.

Program 3: Generic Exponential Search for Comparable Types

Here is a generic version that allows you to search through different data types as long as they support comparison. This could be strings, dates, or any custom type that follows an order.

import Foundation

func genericExponentialSearch<T: Comparable>(_ array: [T], target: T) -> Int? {

    if array.isEmpty {
        return nil
    }

    if array[0] == target {
        return 0
    }

    var bound = 1

    while bound < array.count && array[bound] <= target {
        bound *= 2
    }

    let left = bound / 2
    let right = min(bound, array.count - 1)

    return genericBinarySearch(array, target: target, left: left, right: right)

}

func genericBinarySearch<T: Comparable>(_ array: [T], target: T, left: Int, right: Int) -> Int? {

    var low = left
    var high = right

    while low <= high {

        let mid = low + (high - low) / 2

        if array[mid] == target {
            return mid
        } else if target < array[mid] {
            high = mid - 1
        } else {
            low = mid + 1
        }

    }

    return nil

}

let names = ["Adam", "Brian", "Charlie", "Edward", "Frank", "Samuel"]

if let index = genericExponentialSearch(names, target: "Edward") {
    print("Found at index \(index)")
} else {
    print("Not found")
}

This version helps beginners understand how Swift generics make algorithms reusable. It also reinforces the idea that as long as values can be compared, they can be searched efficiently.

Program 4: Exponential Search With Step-By-Step Tracing

This program prints every step of the exponential jump and binary search phase. It is especially useful for learners who want to understand the internal behavior of the algorithm.

import Foundation

func exponentialSearchTrace(_ array: [Int], target: Int) -> Int? {

    if array.isEmpty {
        print("Array is empty")
        return nil
    }

    if array[0] == target {
        print("Target matches first element")
        return 0
    }

    var bound = 1

    while bound < array.count && array[bound] <= target {
        print("Checking bound \(bound), value \(array[bound])")
        bound *= 2
    }

    let left = bound / 2
    let right = min(bound, array.count - 1)

    print("Binary search range: \(left) to \(right)")

    return binarySearchTrace(array, target: target, left: left, right: right)

}

func binarySearchTrace(_ array: [Int], target: Int, left: Int, right: Int) -> Int? {

    var low = left
    var high = right

    while low <= high {

        let mid = low + (high - low) / 2

        print("Checking mid \(mid), value \(array[mid])")

        if array[mid] == target {
            return mid
        }

        if target < array[mid] {
            high = mid - 1
        } else {
            low = mid + 1
        }

    }

    return nil

}

let values = [1, 4, 7, 11, 18, 23, 29, 40]

if let index = exponentialSearchTrace(values, target: 23) {
    print("Found at index \(index)")
} else {
    print("Not found")
}

This tracing version is great for learning because it reveals the “jump and zoom-in” nature of the algorithm. Each printed step shows how quickly Exponential Search narrows down the possibilities.

Program 5: Exponential Search as a Swift Array Extension

This example adds Exponential Search directly to the Array type, making it feel like a built-in tool.

import Foundation

extension Array where Element: Comparable {

    func exponentialSearch(target: Element) -> Int? {

        if self.isEmpty {
            return nil
        }

        if self[0] == target {
            return 0
        }

        var bound = 1

        while bound < self.count && self[bound] <= target {
            bound *= 2
        }

        let left = bound / 2
        let right = Swift.min(bound, self.count - 1)

        return self.binarySearch(target: target, left: left, right: right)

    }

    private func binarySearch(target: Element, left: Int, right: Int) -> Int? {

        var low = left
        var high = right

        while low <= high {

            let mid = low + (high - low) / 2

            if self[mid] == target {
                return mid
            }

            if target < self[mid] {
                high = mid - 1
            } else {
                low = mid + 1
            }

        }

        return nil

    }

}

let items = [2, 6, 13, 17, 26, 39, 52]

if let index = items.exponentialSearch(target: 26) {
    print("Found at index \(index)")
} else {
    print("Not found")
}

This version makes the search feel clean and natural, letting you call it directly on any sorted array. It teaches beginners how to wrap algorithms inside Swift extensions to make reusable tools.

Frequently Asked Questions (FAQ)

This section answers the most common questions learners ask while exploring Exponential Search.

Q1. Does Exponential Search require sorted data?
Yes, it only works on sorted arrays. Without sorting, the doubling phase cannot predict the correct search direction.

Q2. Is Exponential Search faster than Binary Search?
Both share the same time complexity in the worst case, but Exponential Search can be faster when the target is near the beginning of the array.

Q3. Why does the algorithm double the range instead of moving linearly?
Doubling allows the algorithm to reach the correct area much faster than checking every element one by one.

Q4. Can Exponential Search work on strings or other types?
It can work with any comparable type as long as the data is sorted, which is why the generic example is useful.

Q5. When is Exponential Search used in real life?
It is helpful for very large sorted datasets, especially when quick access to early elements is common. It also appears in search engines and indexing systems.

Conclusion

Exponential Search is a great algorithm for Swift beginners who want to explore ways of searching smarter rather than harder. By combining rapid range expansion with the accuracy of Binary Search, it offers a balanced and efficient way to look up values in sorted arrays. From the basic version to the generic and extension-based versions, each example shows a different way to make the algorithm fit naturally into your Swift projects. With practice, you will gain a stronger sense of how search algorithms work and discover how to build your own tools using Swift’s clean and expressive style.

Scroll to Top