📜  在几乎排序的数组中搜索

📅  最后修改于: 2021-04-24 21:47:26             🧑  作者: Mango

给定一个已排序的数组,但是在排序之后,一些元素将移动到两个相邻位置中的任意一个,即arr [i]可能出现在arr [i + 1]或arr [i-1]处。编写一个有效的函数来搜索此数组中的元素。基本上,元素arr [i]只能与arr [i + 1]或arr [i-1]交换。

例如,考虑将数组{2、3、10、4、40},4移动到下一个位置,将10移动到上一个位置。

例子 :

Input: arr[] =  {10, 3, 40, 20, 50, 80, 70}, key = 40
Output: 2 
Output is index of 40 in given array

Input: arr[] =  {10, 3, 40, 20, 50, 80, 70}, key = 90
Output: -1
-1 is returned to indicate element is not present

一个简单的解决方案是线性搜索给定数组中的给定键。该解决方案的时间复杂度为O(n)。我们可以修改二进制搜索以在O(Logn)时间执行此操作。

想法是将键与中间的3个元素进行比较(如果存在),然后返回索引。如果不存在,则将键与中间元素进行比较,以决定要移入左半部分还是右半部分。与mid元素进行比较就足够了,因为mid + 2之后的所有元素都必须大于element mid,而mid-2之前的所有元素都必须小于mid元素。

以下是此方法的实现。

C++
// C++ program to find an element 
// in an almost sorted array
#include 
  
// A recursive binary search based function. 
// It returns index 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 
        // one of the middle 3 positions
        if (arr[mid] == x) 
            return mid;
        if (mid > l && arr[mid - 1] == x)
            return (mid - 1);
        if (mid < r && arr[mid + 1] == x) 
            return (mid + 1);
  
        // If element is smaller than mid, then 
        // it can only be present in left subarray
        if (arr[mid] > x) 
            return binarySearch(arr, l, mid - 2, x);
  
        // Else the element can only be present 
        // in right subarray
        return binarySearch(arr, mid + 2, r, x);
}
  
// We reach here when element is not present in array
return -1;
}
  
// Driver Code
int main(void)
{
int arr[] = {3, 2, 10, 4, 40};
int n = sizeof(arr) / sizeof(arr[0]);
int x = 4;
int result = binarySearch(arr, 0, n - 1, 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 
// in an almost sorted array
class GFG
{
    // A recursive binary search based function. 
    // It returns index 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 
            // one of the middle 3 positions
            if (arr[mid] == x) 
                return mid;
            if (mid > l && arr[mid - 1] == x)
                return (mid - 1);
            if (mid < r && arr[mid + 1] == x)
                return (mid + 1);
  
            // If element is smaller than mid, then
            // it can only be present in left subarray
            if (arr[mid] > x) 
                return binarySearch(arr, l, mid - 2, x);
  
            // Else the element can only be present 
            // in right subarray
            return binarySearch(arr, mid + 2, r, x);
        }
  
        // We reach here when element is 
        // not present in array
        return -1;
    }
  
    // Driver code
    public static void main(String args[])
    {
        GFG ob = new GFG();
        int arr[] = {3, 2, 10, 4, 40};
        int n = arr.length;
        int x = 4;
        int result = ob.binarySearch(arr, 0, n - 1, x);
        if(result == -1)
            System.out.println("Element is not present in array");
        else
            System.out.println("Element is present at index " +
                                result);
    }
}
  
// This code is contributed by Rajat Mishra


Python3
# Python 3 program to find an element 
# in an almost sorted array
  
# A recursive binary search based function. 
# It returns index of x in given array arr[l..r]
# is present, otherwise -1
def binarySearch(arr, l, r, x):
  
    if (r >= l):
          
        mid = int(l + (r - l) / 2)
          
        # If the element is present at one 
        # of the middle 3 positions
        if (arr[mid] == x): return mid
        if (mid > l and arr[mid - 1] == x): 
            return (mid - 1)
        if (mid < r and arr[mid + 1] == x):
            return (mid + 1)
              
        # If element is smaller than mid, then 
        # it can only be present in left subarray
        if (arr[mid] > x):
            return binarySearch(arr, l, mid - 2, x)
          
        # Else the element can only
        # be present in right subarray
        return binarySearch(arr, mid + 2, r, x)
  
    # We reach here when element
    # is not present in array
    return -1
  
# Driver Code
arr = [3, 2, 10, 4, 40]
n = len(arr)
x = 4
result = binarySearch(arr, 0, n - 1, x)
if (result == -1): 
    print("Element is not present in array") 
else:
    print("Element is present at index", result)
  
# This code is contributed by Smitha Dinesh Semwal.


C#
// C# program to find an element 
// in an almost sorted array
using System;
  
class GFG
{
    // A recursive binary search based function.
    // It returns index 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 
            // one of the middle 3 positions
            if (arr[mid] == x) 
                return mid;
            if (mid > l && arr[mid - 1] == x) 
                return (mid - 1);
            if (mid < r && arr[mid + 1] == x) 
                return (mid + 1);
  
            // If element is smaller than mid, then 
            // it can only be present in left subarray
            if (arr[mid] > x) 
                return binarySearch(arr, l, mid - 2, x);
  
            // Else the element can only be present 
            // in right subarray
            return binarySearch(arr, mid + 2, r, x);
        }
  
        // We reach here when element is 
        // not present in array
        return -1;
    }
  
    // Driver code
    public static void Main()
    {
        GFG ob = new GFG();
        int []arr = {3, 2, 10, 4, 40};
        int n = arr.Length;
        int x = 4;
        int result = ob.binarySearch(arr, 0, n - 1, 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 nitin mittal.


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


输出 :

Element is present at index 3

上述函数的时间复杂度为O(Logn)。