用于在排序和旋转数组中搜索元素的 C 程序
通过二进制搜索,可以在 O(log n) 时间内找到排序数组中的元素。但是假设我们在你事先不知道的某个枢轴上旋转一个升序排序的数组。因此,例如,1 2 3 4 5 可能会变成 3 4 5 1 2。设计一种方法来在 O(log n) 时间内找到旋转数组中的元素。
例子:
Input : arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3};
key = 3
Output : Found at index 8
Input : arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3};
key = 30
Output : Not found
Input : arr[] = {30, 40, 50, 10, 20}
key = 10
Output : Found at index 3
此处提供的所有解决方案都假定数组中的所有元素都是不同的。
基本解决方案:
方法:
- 这个想法是找到枢轴点,将数组分成两个子数组并执行二进制搜索。
- 寻找枢轴的主要思想是——对于一个排序(按递增顺序)和枢轴数组,枢轴元素是唯一一个其下一个元素小于它的元素。
- 使用上面的语句和二分查找可以找到pivot。
- 找到主元后,将数组分成两个子数组。
- 现在对各个子数组进行排序,以便可以使用二进制搜索来搜索元素。
执行:
Input arr[] = {3, 4, 5, 1, 2}
Element to Search = 1
1) Find out pivot point and divide the array in two
sub-arrays. (pivot = 2) /*Index of 5*/
2) Now call binary search for one of the two sub-arrays.
(a) If element is greater than 0th element then
search in left array
(b) Else Search in right array
(1 will go in else as 1 < 0th element(3))
3) If element is found in selected sub-array then return index
Else return -1.
下面是上述方法的实现:
C
/* Program to search an element in
a sorted and pivoted array*/
#include
int findPivot(int[], int, int);
int binarySearch(int[], int, int, int);
/* Searches an element key in a pivoted
sorted array arrp[] of size n */
int pivotedBinarySearch(int arr[], int n, int key)
{
int pivot = findPivot(arr, 0, n - 1);
// If we didn't find a pivot,
// then array is not rotated at all
if (pivot == -1)
return binarySearch(arr, 0, n - 1, key);
// If we found a pivot, then first
// compare with pivot and then
// search in two subarrays around pivot
if (arr[pivot] == key)
return pivot;
if (arr[0] <= key)
return binarySearch(arr, 0, pivot - 1, key);
return binarySearch(arr, pivot + 1, n - 1, key);
}
/* Function to get pivot. For array
3, 4, 5, 6, 1, 2 it returns 3 (index of 6) */
int findPivot(int arr[], int low, int high)
{
// base cases
if (high < low)
return -1;
if (high == low)
return low;
int mid = (low + high) / 2; /*low + (high - low)/2;*/
if (mid < high && arr[mid] > arr[mid + 1])
return mid;
if (mid > low && arr[mid] < arr[mid - 1])
return (mid - 1);
if (arr[low] >= arr[mid])
return findPivot(arr, low, mid - 1);
return findPivot(arr, mid + 1, high);
}
/* Standard Binary Search function*/
int binarySearch(int arr[], int low, int high, int key)
{
if (high < low)
return -1;
int mid = (low + high) / 2; /*low + (high - low)/2;*/
if (key == arr[mid])
return mid;
if (key > arr[mid])
return binarySearch(arr, (mid + 1), high, key);
return binarySearch(arr, low, (mid - 1), key);
}
/* Driver program to check above functions */
int main()
{
// Let us search 3 in below array
int arr1[] = { 5, 6, 7, 8, 9, 10, 1, 2, 3 };
int n = sizeof(arr1) / sizeof(arr1[0]);
int key = 3;
printf("Index of the element is : %d",
pivotedBinarySearch(arr1, n, key));
return 0;
}
输出:
Index of the element is : 8
复杂性分析:
- 时间复杂度: O(log n)。
二进制搜索需要进行 log n 次比较才能找到元素。所以时间复杂度是O(log n)。 - 空间复杂度: O(1),不需要额外的空间。
有关详细信息,请参阅有关在排序和旋转数组中搜索元素的完整文章!