可以在未排序的数组中应用二进制搜索吗
搜索算法旨在检查元素或从存储元素的任何数据结构中检索元素。主要被广泛使用的搜索算法有:
- 线性搜索
- 二进制搜索
线性搜索:在这种情况下,列表或数组按顺序遍历并检查每个元素。线性搜索可以在已排序和未排序的数组或列表上实现。线性搜索具有线性时间复杂度,即O(N)
二分搜索:它是一种搜索算法,专为在已排序的数据结构中搜索而设计。这种搜索算法比线性搜索更有效,因为它们反复瞄准搜索结构的中心并将搜索空间分成两半。它具有对数时间复杂度,即O(log N) 。
现在,问题出现了,二分搜索是否适用于未排序的数组?
So, the answer is NO, it is not possible to use or implement Binary Search on unsorted arrays or lists, because, the repeated targeting of the mid element of one half depends on the sorted order of data structure.
在未排序的数组中应用二进制搜索的解决方法:
但是,如果需要明确地这样做,那么:
Construct an auxiliary array of pairs of elements with their indices and simply sort the array and perform binary search for given X on sorted auxiliary array
请按照以下步骤操作:
- 对于数组中的每个元素,将元素及其索引写入辅助数组对中。
- 排序辅助数组。
- 对于给定的值X对已排序的辅助数组执行二进制搜索,
- 令position为元素X在辅助数组中的索引。
- 返回原始数组 arr(aux_array[position].second) 中元素的索引。
下面是上述方法的实现:
C++
// C++ program for the above approach:
#include
using namespace std;
vector > aux_arr;
// Function to make auxiliary array
void make_aux_array(int arr[], int n)
{
aux_arr.resize(n);
// For every element in array write
// elements and their indices in
// auxiliary array of pairs.
for (int i = 0; i < n; i++) {
aux_arr[i] = { arr[i], i };
}
// Sort auxiliary array.
sort(aux_arr.begin(), aux_arr.end());
}
// Function to perform binary search
int binarySearch(int arr[], int n, int x)
{
// For given value x perform
// Binary Search on sorted auxiliary
// array, let position be the index
// where element x is in
// auxiliary array.
int position
= lower_bound(aux_arr.begin(),
aux_arr.end(),
make_pair(x, 0))
- aux_arr.begin();
if (position < n
&& aux_arr[position].first == x) {
// Return index of element in
// original array arr
// (aux_array[position].second).
return aux_arr[position].second;
}
else {
return -1;
}
}
// Print Function
void print(int arr[], int n, int x)
{
make_aux_array(arr, n);
int result = binarySearch(arr, n, x);
if (result == -1) {
cout << -1 << endl;
}
else {
cout << result << endl;
}
}
// Driver code
int main()
{
int arr[] = { 15, 12, 13, 19, 11,
10, 18, 17, 14, 16 };
int N = sizeof(arr) / sizeof(arr[0]);
int X = 18;
// Function call
print(arr, N, X);
return 0;
}
C
// C program to implement above approach
#include
#include
// Structure to make a pair
typedef struct {
int value, index;
} pair;
// Function to compare pairs
int cmp_pair(const void* a, const void* b)
{
return ((*(pair*)a).value
- (*(pair*)b).value);
}
pair* aux_arr;
// Function to mak auxiliary array
void make_aux_array(int arr[], int n)
{
aux_arr = (pair*)malloc(n * sizeof(pair));
// For every element in array
// write elements and
// their indices in auxiliary array
for (int i = 0; i < n; i++) {
aux_arr[i].value = arr[i];
aux_arr[i].index = i;
}
// Sort auxiliary array.
qsort(aux_arr, n, sizeof(pair),
cmp_pair);
}
// Function to implement binary search
int binarySearch(int arr[], int n, int x)
{
// For given value x perform Bnary Search
// on sorted auxiliary array.
// Let position be the index where
// element x is in auxiliary array.
pair key = { x, 0 };
pair* found = (pair*)bsearch(
&key, aux_arr, n, sizeof(pair), cmp_pair);
if (found != NULL) {
int position = found - aux_arr;
// Return index of element
// in original array arr
// (aux_array[position].second).
return aux_arr[position].index;
}
else {
return -1;
}
}
// Driver code
int main()
{
int arr[] = { 15, 12, 13, 19, 11,
10, 18, 17, 14, 16 };
int x = 18;
int n = sizeof(arr) / sizeof(arr[0]);
make_aux_array(arr, n);
// Function call
int result = binarySearch(arr, n, x);
printf("%d\n", result);
return 0;
}
6
时间复杂度: O(N*log N)
- 排序辅助数组 O(N* log N)
- 二分查找 O(log N)
辅助空间: O(N)
结论:从变通方法中可以看出,使用二分查找相比线性查找需要更多的时间,并且还占用了额外的空间。所以不推荐对未排序的数组使用二分查找。