【算法】折半查找

复习时看见了就记录一下吧。

折半查找,也称二分查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组已经为空,则表示找不到指定的元素。这种搜索算法每一次比较都使搜索范围缩小一半,其时间复杂度是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(>>>是逻辑右移,是不带符号位的右移)

原文地址:https://www.cnblogs.com/2YSP/p/9018873.html