Rust Program to Implement Interpolation Search

Rust Program to Implement Interpolation Search

Interpolation Search is an efficient searching algorithm that works on sorted arrays by estimating the position of the target element. Unlike Binary Search, which always looks in the middle, Interpolation Search predicts where the element might be based on the values of the elements. This can make it faster than Binary Search when the data is uniformly distributed.

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

For beginners learning Rust, Interpolation Search is a great way to understand how algorithms can “guess” positions and adapt the search accordingly. It is widely used in searching applications where numbers are evenly spaced, such as in telephone directories, grade records, or indexed datasets. Learning it also strengthens your understanding of loops, arithmetic operations, and conditional logic in Rust.

Program 1: Iterative Interpolation Search on Integers

This program demonstrates Interpolation Search using a loop on a sorted array of integers. It calculates the estimated position of the target based on the value range.

fn interpolation_search(arr: &[i32], target: i32) -> Option<usize> {

    let mut low = 0;
    let mut high = arr.len() - 1;

    while low <= high && target >= arr[low] && target <= arr[high] {

        let pos = low + (((high - low) as i32 * (target - arr[low])) / (arr[high] - arr[low])) as usize;

        if arr[pos] == target {
            return Some(pos);
        } else if arr[pos] < target {
            low = pos + 1;
        } else {
            if pos == 0 { break; }
            high = pos - 1;
        }

    }

    None

}

fn main() {

    let numbers = [10, 20, 30, 40, 50, 60, 70];
    let target = 40;

    println!("Array: {:?}", numbers);

    match interpolation_search(&numbers, target) {

        Some(idx) => println!("Element {} found at index {}", target, idx),
        None => println!("Element {} not found", target),

    }

}

This program estimates the target’s likely position, reducing unnecessary comparisons. Beginners can see how arithmetic is used to optimize search instead of simply halving the range like Binary Search.

Program 2: Recursive Interpolation Search

Recursion provides a clean and elegant approach. This version calls itself with the updated search range until the target is found or the range is invalid.

fn interpolation_search_recursive(arr: &[i32], target: i32, low: usize, high: usize) -> Option<usize> {

    if low > high || target < arr[low] || target > arr[high] {
        return None;
    }

    let pos = low + (((high - low) as i32 * (target - arr[low])) / (arr[high] - arr[low])) as usize;

    if arr[pos] == target {
        return Some(pos);
    } else if arr[pos] < target {
        return interpolation_search_recursive(arr, target, pos + 1, high);
    } else {
        if pos == 0 { return None; }
        return interpolation_search_recursive(arr, target, low, pos - 1);
    }

}

fn main() {

    let numbers = [5, 15, 25, 35, 45, 55];
    let target = 25;

    println!("Array: {:?}", numbers);

    match interpolation_search_recursive(&numbers, target, 0, numbers.len() - 1) {

        Some(idx) => println!("Element {} found at index {}", target, idx),
        None => println!("Element {} not found", target),

    }

}

Recursion allows the algorithm to reduce the problem size elegantly. Beginners can practice tracing the recursive calls to understand how the search “zooms in” on the target.

Program 3: Interpolation Search with Debug Statements

Adding debug prints helps visualize the position estimation and understand how the algorithm narrows the search.

fn interpolation_search_debug(arr: &[i32], target: i32) -> Option<usize> {

    let mut low = 0;
    let mut high = arr.len() - 1;

    while low <= high && target >= arr[low] && target <= arr[high] {

        let pos = low + (((high - low) as i32 * (target - arr[low])) / (arr[high] - arr[low])) as usize;
        println!("Checking position {}: value {}", pos, arr[pos]);

        if arr[pos] == target {
            return Some(pos);
        } else if arr[pos] < target {
            low = pos + 1;
        } else {
            if pos == 0 { break; }
            high = pos - 1;
        }

    }

    None

}

fn main() {

    let numbers = [2, 4, 6, 8, 10, 12];
    let target = 10;

    println!("Array: {:?}", numbers);

    match interpolation_search_debug(&numbers, target) {
        Some(idx) => println!("Element {} found at index {}", target, idx),
        None => println!("Element {} not found", target),
    }

}

Debugging illustrates how Interpolation Search moves closer to the target efficiently. Beginners can see how the calculation affects which index is checked next.

Program 4: Interpolation Search on Floating-Point Numbers

Interpolation Search works for floats as well. This example demonstrates searching in a sorted array of decimal numbers.

fn interpolation_search_floats(arr: &[f64], target: f64) -> Option<usize> {

    let mut low = 0;
    let mut high = arr.len() - 1;

    while low <= high && target >= arr[low] && target <= arr[high] {

        let pos = low + (((high - low) as f64 * (target - arr[low]) / (arr[high] - arr[low])) as usize);

        if (arr[pos] - target).abs() < std::f64::EPSILON {
            return Some(pos);
        } else if arr[pos] < target {
            low = pos + 1;
        } else {
            if pos == 0 { break; }
            high = pos - 1;
        }

    }

    None

}

fn main() {

    let numbers = [1.0, 2.5, 3.5, 4.0, 5.5];
    let target = 3.5;

    println!("Array: {:?}", numbers);

    match interpolation_search_floats(&numbers, target) {
        Some(idx) => println!("Element {} found at index {}", target, idx),
        None => println!("Element {} not found", target),
    }

}

This program demonstrates how Interpolation Search can handle fractional numbers with precision. Beginners can learn to combine math calculations with conditional checks in Rust.

Program 5: Interpolation Search with Early Exit

This version shows how to quickly terminate the search when the array is small or the target is outside the expected range.

fn interpolation_search_early_exit(arr: &[i32], target: i32) -> Option<usize> {

    let mut low = 0;
    let mut high = arr.len() - 1;

    if target < arr[low] || target > arr[high] {
        return None;
    }

    while low <= high {

        let pos = low + (((high - low) as i32 * (target - arr[low])) / (arr[high] - arr[low])) as usize;

        if arr[pos] == target {
            return Some(pos);
        } else if arr[pos] < target {
            low = pos + 1;
        } else {
            if pos == 0 { break; }
            high = pos - 1;
        }

    }

    None

}

fn main() {

    let numbers = [100, 200, 300, 400, 500];
    let target = 50;

    println!("Array: {:?}", numbers);

    match interpolation_search_early_exit(&numbers, target) {

        Some(idx) => println!("Element {} found at index {}", target, idx),
        None => println!("Element {} not found", target),

    }

}

The early exit check ensures efficiency by avoiding unnecessary calculations. Beginners can see how to handle edge cases safely.

Frequently Asked Questions (FAQ)

Q1: What is the time complexity of Interpolation Search?
It has an average time complexity of O(log log n) for uniformly distributed arrays, and O(n) in the worst case.

Q2: Can Interpolation Search work on unsorted arrays?
No, the array must be sorted for correct results.

Q3: When is Interpolation Search better than Binary Search?
It performs better when the data is uniformly distributed, as it can “guess” the target position more accurately.

Q4: Can Interpolation Search handle floats and decimals?
Yes, with careful handling of precision using methods like abs() comparison.

Q5: Is recursion necessary for Interpolation Search?
No, it can be implemented iteratively or recursively. Iterative is generally more memory-efficient.

Conclusion

Interpolation Search is a powerful algorithm for searching sorted, uniformly distributed arrays efficiently. By implementing it in Rust, beginners can explore loops, recursion, and arithmetic-based position estimation. Understanding the iterative, recursive, and debug-friendly approaches helps learners gain confidence in algorithm design. Practicing Interpolation Search strengthens problem-solving skills and lays the groundwork for more advanced searching algorithms.

Scroll to Top