据说10个程序员,有九个写不对二分查找函数。
《编程珠玑》的作者Jon Bentley曾在贝尔实验室做过一个实验,即给一些专业的程序员几个小时的时间,用任何一种语言编写二分查找程序(写出高级伪代码也可以),结果参与编写的一百多人中:90%的程序员写的程序中有bug。
在查看参考程序前,请自行写个二分查找算法,看看自己是否属于那90%的那一部分人。
二分查找即在已排序数组中查找给定数。
给定二分查找算法接口函数如下:
int binarySearch(int A[],int n,int key);
输入:已排序的数组A,数组长度n,待查找的数key
输出:待查找数字key在数组A中的下标,如果没查找到,则返回-1
一个参考程序:
二分查找算法的变体
一个二分查找算法的变体是在被翻转过一次的有序数组中查找特定元素。
“被翻转过的一次有序数组”是什么意思呢?
举个例子,有序数组[1,2,3,4,5,6,7,8,9,10]在以元素6为分割点,进行翻转得到[6,7,8,9,10,1,2,3,4,5],也就是说现在的数组被分成了两段,每段都是有序的。
现在同样给出类似于二分查找算法的接口如下:
int rotateBinarySearch(int A[],int n,int key)
这里的数组A是被翻转过的一次有序数组。如何实现在数组中查找给定数key呢?
我们可以借鉴二分查找算法的思路。
一个参考程序如下(PS:程序没有做输入合法性检查):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
int
rotateBinarySearch
(
int
A
[
]
,
int
n
,
int
key
)
{
int
left
=
0
,
right
=
n
-
1
;
int
mid
;
while
(
left
<=
right
)
{
mid
=
(
left
+
right
)
/
2
;
if
(
A
[
mid
]
==
key
)
return
mid
;
if
(
A
[
left
]
<=
A
[
mid
]
)
{
if
(
A
[
left
]
<=
key
&&
A
[
mid
]
>
key
)
right
=
mid
-
1
;
else
left
=
mid
+
1
;
}
else
{
if
(
A
[
mid
]
<
key
&&
A
[
right
]
>=
key
)
left
=
mid
+
1
;
else
right
=
mid
-
1
;
}
}
return
-
1
;
}
|