📜  可以在未排序的数组中应用二进制搜索吗

📅  最后修改于: 2022-05-13 01:56:10.735000             🧑  作者: Mango

可以在未排序的数组中应用二进制搜索吗

搜索算法旨在检查元素或从存储元素的任何数据结构中检索元素。主要被广泛使用的搜索算法有:

  • 线性搜索
  • 二进制搜索

线性搜索:在这种情况下,列表或数组按顺序遍历并检查每个元素。线性搜索可以在已排序和未排序的数组或列表上实现。线性搜索具有线性时间复杂度,即O(N)

二分搜索:它是一种搜索算法,专为在已排序的数据结构中搜索而设计。这种搜索算法比线性搜索更有效,因为它们反复瞄准搜索结构的中心并将搜索空间分成两半。它具有对数时间复杂度,即O(log N)

现在,问题出现了,二分搜索是否适用于未排序的数组?

在未排序的数组中应用二进制搜索的解决方法:

但是,如果需要明确地这样做,那么:

请按照以下步骤操作:

  • 对于数组中的每个元素,将元素及其索引写入辅助数组对中。
  • 排序辅助数组。
  • 对于给定的值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)

结论:从变通方法中可以看出,使用二分查找相比线性查找需要更多的时间,并且还占用了额外的空间。所以不推荐对未排序的数组使用二分查找。