复习时看见了就记录一下吧。
折半查找,也称二分查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组已经为空,则表示找不到指定的元素。这种搜索算法每一次比较都使搜索范围缩小一半,其时间复杂度是O(logN)。注意前提是,数组已经是有序的才能使用。
1 package cn.sp;
2
3 import java.util.Comparator;
4
5 /**
6 * @Author: 2YSP
7 * @Description: 实现折半查找算法
8 * @Date: Created in 2018/5/10
9 */
10 public class MyUtil {
11
12 /**
13 * 使用循环实现
14 * @param list
15 * @param key
16 * @param comp
17 * @param <T>
18 * @return
19 */
20 public static <T> int binarySearch(T[] list, T key, Comparator<T> comp){
21 int low = 0;
22 int high = list.length - 1;
23 while (low <= high){
24 int mid = (low+high) >>> 1;
25 if (comp.compare(list[mid],key) > 0){
26 high = mid - 1;
27 }else if (comp.compare(list[mid],key) < 0){
28 low = mid + 1;
29 }else {
30 return mid;
31 }
32 }
33
34 return -1;
35 }
36
37 /**
38 * 使用递归实现
39 * @param list
40 * @param low
41 * @param high
42 * @param key
43 * @param <T>
44 * @return
45 */
46 public static <T extends Comparable<T>> int binarySearch(T[] list,int low,int high,T key){
47 if (low <= high){
48 int mid = (low+high) >>> 1;
49 if (list[mid].compareTo(key) > 0){
50 high = mid - 1;
51 binarySearch(list,low,high,key);
52 }else if (list[mid].compareTo(key) < 0){
53 low = mid + 1;
54 binarySearch(list,low,high,key);
55 }else {
56 return mid;
57 }
58 }
59 return -1;
60 }
61
62 public static <T extends Comparable<T>> int binarySearch(T[] list,T key){
63 return binarySearch(list,0,list.length-1,key);
64 }
65
66 public static void main(String[] args) {
67 Integer[] list = {1,3,5,8,10};
68 Integer key = 7;
69 int result = binarySearch(list,key);
70 System.out.println(result);
71 }
72 }
上面的代码中给出了折半查找的两个版本,一个用递归实现,一个用循环实现。需要注意的是计算中间位置时不应该使用(high+ low) / 2的方式,因为加法运算可能导致整数越界,这里应该使用以下三种方式之一:low + (high - low) / 2或low + (high – low) >> 1或(low + high) >>> 1(>>>是逻辑右移,是不带符号位的右移)