题目描述
给定已排好序的 (n) 个元素 (a[0 : n - 1]) ,在这 (n) 个元素中找出某一特定元素 (x) 。
说明
- 输入
- 第一行输入数组元素个数 (n)
- 第二行输入数组各个元素 ({a[0] ... a[n - 1]})
- 第三行输入所要找的元素 (x)
- 输出
- 输出元素 (x) 在数组中的下标,如果不存在则输出 (-1)
示例
输入:
5
1 3 5 7 9
3
输出:
1
输入:
6
1 5 6 10 12 20
9
输出:
-1
题解
首先可以采用顺序查找方法,逐个查找 ({a[0 : n - 1]}) 中的元素,直至找出元素 (x) 或者搜索完整个数组。在最坏情况下,这样做的时间复杂度显然是 (O(N)) 。
顺序查找没有利用数组元素有序的性质。二分查找采用分治策略,将 (n) 个元素分成个数大致相同的两部分,取 (a[n / 2]) 与 (x) 比较。如果 (x) 等于 (a[n / 2]) ,则找到 (x) ,算法结束。如果 (x) 小于 (a[n / 2]) ,则在数组 (a) 的左半部分继续按照此算法继续搜索 (x) ;如果 (x) 大于 (a[n / 2]) ,则在数组 (a) 的右半部分继续按照此算法继续搜索 (x) 。在最坏情况下,二分查找的时间复杂度是 ({O(logN)}) 。
当然,也可以构建哈希表来处理此问题,它的时间复杂度只是 ({O(1)}) 级别。
代码
#include <iostream>
using namespace std;
// 迭代版本
int iterate_binary_search(int *a, int &n, const int &x);
// 递归版本
int recursion_binary_search(int *a, int &n, const int &x);
int recursion_auxiliary(int *a, int &left, int &right, const int &x);
const int size = 100;
int main()
{
int n = 0, i = 0, a[size], x = 0;
cin >> n;
for (i = 0; i < n; i++)
{
cin >> a[i];
}
cin >> x;
cout << iterate_binary_search(a, n, x) << endl;
cout << recursion_binary_search(a, n, x) << endl;
return 0;
}
int iterate_binary_search(int *a, int &n, const int &x)
{
int index = -1;
int left = 0, right = n - 1, middle = 0;
while (left <= right)
{
middle = (left + right) / 2;
if (x == a[middle])
{
index = middle;
break;
}
if (x > a[middle])
{
left = middle + 1;
}
else
{
right = middle - 1;
}
}
return index;
}
int recursion_binary_search(int *a, int &n, const int &x)
{
int left = 0, right = n - 1;
return recursion_auxiliary(a, left, right, x);
}
int recursion_auxiliary(int *a, int &left, int &right, const int &x)
{
if (left > right)
{
return -1;
}
int middle = (left + right) / 2;
if (x == a[middle])
{
return middle;
}
if (x > a[middle])
{
left = middle + 1;
}
else
{
right = middle - 1;
}
return recursion_auxiliary(a, left, right, x);
}