Data Structures and Algorithms 15. Linear Algorithms/Binary Search/Interpolation Search

1. Linear Search

        The simplest strategy for finding data is a linear search, which simply goes through each element to find the target, visits each data point to find a match, when a match is found, the result is returned and the algorithm exits the loop, otherwise, the algorithm continues to find, until the end of the data is reached. The obvious disadvantage of linear lookup is that it is very slow due to the inherent exhaustive search. It has the advantage that it does not require the data to be sorted.

1. Linear search example

public <T extends Comparable<T>> int find(T[] array, T value) {
    for (int i = 0; i < array.length; i++) {
        if (array[i].compareTo(value) == 0) {
            return i;
        }
    }
    return -1;
}

@Test
void LinearSearch()
{
    // just generate data
    Random r = new Random();
    int size = 200;
    int maxElement = 100;
    Integer[] integers
            = Stream.generate(() -> r.nextInt(maxElement)).limit(size).toArray(Integer[]::new);

    // the element that should be found
    Integer shouldBeFound = integers[r.nextInt(size - 1)];

    int atIndex = find(integers, shouldBeFound);

    System.out.println(
            String.format(
                    "Should be found: %d. Found %d at index %d. An array length %d",
                    shouldBeFound, integers[atIndex], atIndex, size));
}

2. Combined with thread linear search

package com.thealgorithms.searches;

import java.util.Scanner;

public class LinearSearchThread {
    public static void main(String[] args) {
        int[] list = new int[200];
        for (int j = 0; j < list.length; j++) {
            list[j] = (int) (Math.random() * 100);
        }
        for (int y : list) {
            System.out.print(y + " ");
        }
        System.out.println();
        System.out.print("Enter number to search for: ");
        Scanner in = new Scanner(System.in);
        int x = in.nextInt();
        Searcher t = new Searcher(list, 0, 50, x);
        Searcher t1 = new Searcher(list, 50, 100, x);
        Searcher t2 = new Searcher(list, 100, 150, x);
        Searcher t3 = new Searcher(list, 150, 200, x);
        t.start();
        t1.start();
        t2.start();
        t3.start();
        try {
            t.join();
            t1.join();
            t2.join();
            t3.join();
        } catch (InterruptedException e) {
        }
        boolean found = t.getResult() || t1.getResult() || t2.getResult() || t3.getResult();
        System.out.println("Found = " + found);
    }
}

class Searcher extends Thread {
    private final int[] arr;
    private final int left, right;
    private final int x;
    private boolean found;

    Searcher(int[] arr, int left, int right, int x) {
        this.arr = arr;
        this.left = left;
        this.right = right;
        this.x = x;
    }

    @Override
    public void run() {
        int k = left;
        found = false;
        while (k < right && !found) {
            if (arr[k++] == x) {
                found = true;
            }
        }
    }

    boolean getResult() {
        return found;
    }
}

2. Binary Search

        The premise of the binary search algorithm is that the data is ordered. The algorithm repeatedly divides the current list into two parts, keeping track of the lowest and highest two indices, until it finds the value it is looking for.

        Binary search is so named because in each iteration, the algorithm splits the data into two parts. If the data has N items, it takes at most O(log N) steps to complete the iteration, which means the running time of the algorithm is O(log N).

/**
 * @param array is an array where the element should be found
 * @param key is an element which should be found
 * @param <T> is any comparable type
 * @return index of the element
 */
public <T extends Comparable<T>> int find1(T[] array, T key) {
    return search(array, key, 0, array.length);
}

/**
 * This method implements the Generic Binary Search
 *
 * @param array The array to make the binary search
 * @param key The number you are looking for
 * @param left The lower bound
 * @param right The upper bound
 * @return the location of the key
 */
private <T extends Comparable<T>> int search(T array[], T key, int left, int right) {
    if (right < left) {
        return -1; // this means that the key not found
    }
    // find median
    int median = (left + right) >>> 1;
    int comp = key.compareTo(array[median]);

    if (comp == 0) {
        return median;
    } else if (comp < 0) {
        return search(array, key, left, median - 1);
    } else {
        return search(array, key, median + 1, right);
    }
}


@Test
    void binary_search()
    {
        // Just generate data
        Random r = ThreadLocalRandom.current();

        int size = 100;
        int maxElement = 100000;

        Integer[] integers
                = IntStream.generate(() -> r.nextInt(maxElement))
                .limit(size)
                .sorted()
                .boxed()
                .toArray(Integer[]::new);

        // The element that should be found
        int shouldBeFound = integers[r.nextInt(size - 1)];
        
        //自己的二分查找
        int atIndex = find1(integers, shouldBeFound);
        
        System.out.println(
                String.format(
                        "Should be found: %d. Found %d at index %d. An array length %d",
                        shouldBeFound, integers[atIndex], atIndex, size));
        //系统的二分查找
        int toCheck = Arrays.binarySearch(integers, shouldBeFound);
        System.out.println(
                String.format(
                        "使用系统的二分查找 index: %d. Is equal: %b", toCheck, toCheck == atIndex));
    }

3. Interpolation Search

        Interpolation search, a search method for ordered lists. Interpolation search is a search method based on the search key and the largest and smallest record keys in the lookup table. Interpolation search is based on binary search, and the selection of search points is improved to adaptive selection to improve search efficiency.

        If the data is not evenly distributed, the performance of the interpolation lookup algorithm will be poor, and the worst time complexity of this algorithm is O(N). If the data is fairly evenly distributed, the optimal time complexity is O(log(log N)). 

/**
 * @param array is a sorted array
 * @param key is a value what shoulb be found in the array
 * @return an index if the array contains the key unless -1
 */
public int find2(int array[], int key) {
    // Find indexes of two corners
    int start = 0, end = (array.length - 1);

    // Since array is sorted, an element present
    // in array must be in range defined by corner
    while (start <= end && key >= array[start] && key <= array[end]) {
        // Probing the position with keeping
        // uniform distribution in mind.
        int pos = start + (((end - start) / (array[end] - array[start])) * (key - array[start]));

        // Condition of target found
        if (array[pos] == key) {
            return pos;
        }

        // If key is larger, key is in upper part
        if (array[pos] < key) {
            start = pos + 1;
        } // If key is smaller, x is in lower part
        else {
            end = pos - 1;
        }
    }
    return -1;

}

@Test
void interpolation_search()
{
    Random r = new Random();
    int size = 100;
    int maxElement = 100000;
    int[] integers = IntStream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray();

    // the element that should be found
    Integer shouldBeFound = integers[r.nextInt(size - 1)];

    int atIndex = find2(integers, shouldBeFound);

    System.out.println(
            String.format(
                    "Should be found: %d. Found %d at index %d. An array length %d",
                    shouldBeFound, integers[atIndex], atIndex, size));

    int toCheck = Arrays.binarySearch(integers, shouldBeFound);
    System.out.println(
            String.format(
                    "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex));
}

Guess you like

Origin blog.csdn.net/bashendixie5/article/details/123569103