1、二分查找(Binary Search)
二分查找又称折半查找,它是一种效率较高的查找方法。
二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构。不妨设有序表是递增有序的。
2、二分查找的基本思想
二分查找的基本思想是:(设R[low..high]是当前的查找区间)
(1)首先确定该区间的中点位置:
(2)然后将待查的K值与R[mid].key比较:若相等,则查找成功并返回此位置,否则须确定新的查找区间,继续二分查找,具体方法如下:
①若R[mid].key>K,则由表的有序性可知R[mid..n].keys均大于K,因此若表中存在关键字等于K的结点,则该结点必定是在位置mid左边的子表R[1..mid-1]中,故新的查找区间是左子表R[1..mid-1]。
②类似地,若R[mid].key<K,则要查找的K必在mid的右子表R[mid+1..n]中,即新的查找区间是右子表R[mid+1..n]。下一次查找是针对新的查找区间进行的。
因此,从初始的查找区间R[1..n]开始,每经过一次与当前查找区间的中点位置上的结点关键字的比较,就可确定查找是否成功,不成功则当前的查找区间就缩小一半。这一过程重复直至找到关键字为K的结点,或者直至当前的查找区间为空(即查找失败)时为止。
1 /**
2 * 非递归二分查找
3 * @param array $array 要查找的数组
4 * @param int $key 要找的元素
5 */
6 function binary_search($array, $key) {
7 $low = 0;
8 $high = count ( $array ) - 1;
9 while ( $low <= $high ) {
10 $mid = ceil ( ($low + $high) / 2 );
11 if ($key == $array [$mid]) {
12 return $mid;
13 }
14 if ($key > $array [$mid]) {
15 $low = $mid + 1;
16 } else {
17 $high = $mid - 1;
18 }
19 }
20 return FALSE;
21 }
22
23 /**
24 * 递归二分查找
25 * @param array $array 要查找的数组
26 * @param int $key 要找的元素
27 * @param int $low 第一个元素的索引
28 * @param int $high 最后一个元素的索引
29 */
30 function binary_search_recursive($array, $key, $low = FALSE, $high = FALSE) {
31 if (FALSE === $low || FALSE === $high) {
32 $low = 0;
33 $high = count ( $array ) - 1;
34 }
35 while ( $low <= $high ) {
36 $mid = ceil ( ($low + $high) / 2 );
37 if ($key == $array [$mid]) {
38 return $mid;
39 }
40 if ($key > $array [$mid]) {
41 return binary_search_recursive ( $array, $key, $mid + 1, $high );
42 } else {
43 return binary_search_recursive ( $array, $key, $low, $high - 1 );
44 }
45 }
46 return FALSE;
47 }
48 var_dump ( binary_search ( range ( 1, 10 ), 3 ) );
49 var_dump ( binary_search_recursive ( range ( 1, 10 ), 3 ) );
2 * 非递归二分查找
3 * @param array $array 要查找的数组
4 * @param int $key 要找的元素
5 */
6 function binary_search($array, $key) {
7 $low = 0;
8 $high = count ( $array ) - 1;
9 while ( $low <= $high ) {
10 $mid = ceil ( ($low + $high) / 2 );
11 if ($key == $array [$mid]) {
12 return $mid;
13 }
14 if ($key > $array [$mid]) {
15 $low = $mid + 1;
16 } else {
17 $high = $mid - 1;
18 }
19 }
20 return FALSE;
21 }
22
23 /**
24 * 递归二分查找
25 * @param array $array 要查找的数组
26 * @param int $key 要找的元素
27 * @param int $low 第一个元素的索引
28 * @param int $high 最后一个元素的索引
29 */
30 function binary_search_recursive($array, $key, $low = FALSE, $high = FALSE) {
31 if (FALSE === $low || FALSE === $high) {
32 $low = 0;
33 $high = count ( $array ) - 1;
34 }
35 while ( $low <= $high ) {
36 $mid = ceil ( ($low + $high) / 2 );
37 if ($key == $array [$mid]) {
38 return $mid;
39 }
40 if ($key > $array [$mid]) {
41 return binary_search_recursive ( $array, $key, $mid + 1, $high );
42 } else {
43 return binary_search_recursive ( $array, $key, $low, $high - 1 );
44 }
45 }
46 return FALSE;
47 }
48 var_dump ( binary_search ( range ( 1, 10 ), 3 ) );
49 var_dump ( binary_search_recursive ( range ( 1, 10 ), 3 ) );
1 // 经过改正过的二分查找
2 function binary_search($array, $key) {
3 $low = 0;
4 $high = count($array) - 1;
5 $mid = floor(($low + $high) / 2);
6 while($array[$mid] != $key && $low < $high) {
7 if ($key < $array[$mid]) {
8 $high = $mid - 1;
9 } else {
10 $low = $mid + 1;
11 }
12 $mid = floor(($low + $high) / 2);
13 }
14 return $array[$mid] != $key ? -1 : $mid;
15 }
3 $low = 0;
4 $high = count($array) - 1;
5 $mid = floor(($low + $high) / 2);
6 while($array[$mid] != $key && $low < $high) {
7 if ($key < $array[$mid]) {
8 $high = $mid - 1;
9 } else {
10 $low = $mid + 1;
11 }
12 $mid = floor(($low + $high) / 2);
13 }
14 return $array[$mid] != $key ? -1 : $mid;
15 }