📜  指数搜索

📅  最后修改于: 2021-05-05 02:50:53             🧑  作者: Mango

该搜索算法的名称可能会误导O(Log n)时间,因此可能会产生误导。名称来自其搜索元素的方式。

Given a sorted array, and an element x to be 
searched, find position of x in the array.

Input:  arr[] = {10, 20, 40, 45, 55}
        x = 45
Output: Element found at index 3

Input:  arr[] = {10, 15, 25, 45, 55}
        x = 15
Output: Element found at index 1

我们已经讨论了线性搜索,二进制搜索来解决这个问题。
指数搜索涉及两个步骤:

  1. 查找元素存在的范围
  2. 在找到的上述范围内进行二进制搜索。

如何找到元素可能存在的范围?
想法是从子数组大小1开始,将其最后一个元素与x进行比较,然后尝试大小2,然后尝试4,依此类推,直到子数组的最后一个元素不更大为止。
一旦找到索引i(在i重复翻倍之后),我们就知道该元素必须存在于i / 2和i之间(为什么要使用i / 2 ?,因为在先前的迭代中找不到更大的值)
以下是上述步骤的实现。

C++
// C++ program to find an element x in a
// sorted array using Exponential search.
#include 
using namespace std;
 
int binarySearch(int arr[], int, int, int);
 
// Returns position of first occurrence of
// x in array
int exponentialSearch(int arr[], int n, int x)
{
    // If x is present at firt location itself
    if (arr[0] == x)
        return 0;
 
    // Find range for binary search by
    // repeated doubling
    int i = 1;
    while (i < n && arr[i] <= x)
        i = i*2;
 
    //  Call binary search for the found range.
    return binarySearch(arr, i/2,
                            min(i, n-1), x);
}
 
// A recursive binary search function. It returns
// location of x in  given array arr[l..r] is
// present, otherwise -1
int binarySearch(int arr[], int l, int r, int x)
{
    if (r >= l)
    {
        int mid = l + (r - l)/2;
 
        // If the element is present at the middle
        // itself
        if (arr[mid] == x)
            return mid;
 
        // If element is smaller than mid, then it
        // can only be present n left subarray
        if (arr[mid] > x)
            return binarySearch(arr, l, mid-1, x);
 
        // Else the element can only be present
        // in right subarray
        return binarySearch(arr, mid+1, r, x);
    }
 
    // We reach here when element is not present
    // in array
    return -1;
}
 
// Driver code
int main(void)
{
   int arr[] = {2, 3, 4, 10, 40};
   int n = sizeof(arr)/ sizeof(arr[0]);
   int x = 10;
   int result = exponentialSearch(arr, n, x);
   (result == -1)? printf("Element is not
                            present in array")
                 : printf("Element is present
                                 at index %d",
                                       result);
   return 0;
}


Java
// Java program to
// find an element x in a
// sorted array using
// Exponential search.
import java.util.Arrays;
 
class GFG
{
    // Returns position of
    // first occurrence of
    // x in array
    static int exponentialSearch(int arr[],
                                 int n, int x)
    {
        // If x is present at firt location itself
        if (arr[0] == x)
            return 0;
     
        // Find range for binary search by
        // repeated doubling
        int i = 1;
        while (i < n && arr[i] <= x)
            i = i*2;
     
        // Call binary search for the found range.
        return Arrays.binarySearch(arr, i/2,
                              Math.min(i, n-1), x);
    }
     
    // Driver code
    public static void main(String args[])
    {
        int arr[] = {2, 3, 4, 10, 40};
        int x = 10;
        int result = exponentialSearch(arr,
                                  arr.length, x);
         
        System.out.println((result < 0) ?
          "Element is not present in array" :
          "Element is present at index " +
                             result);
    }
}


Python
# Python program to find an element x
# in a sorted array using Exponential Search
 
# A recurssive binary search function returns
# location  of x in given array arr[l..r] is
# present, otherwise -1
def binarySearch( arr, l, r, x):
    if r >= l:
        mid = l + ( r-l ) / 2
         
        # If the element is present at
        # the middle itself
        if arr[mid] == x:
            return mid
         
        # If the element is smaller than mid,
        # then it can only be present in the
        # left subarray
        if arr[mid] > x:
            return binarySearch(arr, l,
                                mid - 1, x)
         
        # Else he element can only be
        # present in the right
        return binarySearch(arr, mid + 1, r, x)
         
    # We reach here if the element is not present
    return -1
 
# Returns the position of first
# occurrence of x in array
def exponentialSearch(arr, n, x):
    # IF x is present at first
    # location itself
    if arr[0] == x:
        return 0
         
    # Find range for binary search
    # j by repeated doubling
    i = 1
    while i < n and arr[i] <= x:
        i = i * 2
     
    # Call binary search for the found range
    return binarySearch( arr, i / 2,
                         min(i, n-1), x)
     
 
# Driver Code
arr = [2, 3, 4, 10, 40]
n = len(arr)
x = 10
result = exponentialSearch(arr, n, x)
if result == -1:
    print "Element not found in thye array"
else:
    print "Element is present at index %d" %(result)
 
# This code is contributed by Harshit Agrawal


C#
// C# program to find an element x in a
// sorted array using Exponential search.
using System;
class GFG {
 
// Returns position of first
// occurrence of x in array
static int exponentialSearch(int []arr,
                         int n, int x)
{
     
    // If x is present at
    // first location itself
    if (arr[0] == x)
        return 0;
 
    // Find range for binary search
    // by repeated doubling
    int i = 1;
    while (i < n && arr[i] <= x)
        i = i * 2;
 
    // Call binary search for
    // the found range.
    return binarySearch(arr, i/2,
                       Math.Min(i, n - 1), x);
}
 
// A recursive binary search
// function. It returns location
// of x in given array arr[l..r] is
// present, otherwise -1
static int binarySearch(int []arr, int l,
                        int r, int x)
{
    if (r >= l)
    {
        int mid = l + (r - l) / 2;
 
        // If the element is present
        // at the middle itself
        if (arr[mid] == x)
            return mid;
 
        // If element is smaller than
        // mid, then it can only be
        // present n left subarray
        if (arr[mid] > x)
            return binarySearch(arr, l, mid - 1, x);
 
        // Else the element can only
        // be present in right subarray
        return binarySearch(arr, mid + 1, r, x);
    }
 
    // We reach here when element
    // is not present in array
    return -1;
}
 
// Driver code
public static void Main()
{
    int []arr = {2, 3, 4, 10, 40};
    int n = arr.Length;
    int x = 10;
    int result = exponentialSearch(arr, n, x);
    if (result == -1)
            Console.Write("Element is not
                          present in array");
        else
            Console.Write("Element is
                           present at index "
                                   + result);
}
}
 
// This code is contributed by Smitha


PHP
= $l)
    {
        $mid = $l + ($r - $l)/2;
 
        // If the element is
        // present at the middle
        // itself
        if ($arr[$mid] == $x)
            return $mid;
 
        // If element is smaller
        // than mid, then it
        // can only be present
        // n left subarray
        if ($arr[$mid] > $x)
            return binarySearch($arr, $l,
                                $mid - 1, $x);
 
        // Else the element
        // can only be present
        // in right subarray
        return binarySearch($arr, $mid + 1,
                                    $r, $x);
    }
 
    // We reach here when
    // element is not present
    // in array
    return -1;
}
 
// Driver code
$arr = array(2, 3, 4, 10, 40);
$n = count($arr);
$x = 10;
$result = exponentialSearch($arr, $n, $x);
if($result == -1)
    echo "Element is not present in array";
else
    echo "Element is present at index ",
                                $result;
 
// This code is contributed by anuj_67
?>


Javascript


输出
Element is present at index 3

时间复杂度: O(Log n)
辅助空间:二进制搜索的上述实现是递归的,并且需要O(Log n)空间。使用迭代二进制搜索,我们只需要O(1)空间。
指数搜索的应用:

  1. 指数二进制搜索对于数组大小无限的无界搜索特别有用。请参考“无界二进制搜索”的示例。
  2. 它比二进制搜索有界数组更好,并且当要搜索的元素更靠近第一个元素时,它的工作效果也更好。