• Collections之二分查找


    源码如下:

     1 /**
     2      * Searches the specified list for the specified object using the binary
     3      * search algorithm.  The list must be sorted into ascending order
     4      * according to the {@linkplain Comparable natural ordering} of its
     5      * elements (as by the {@link #sort(List)} method) prior to making this
     6      * call.  If it is not sorted, the results are undefined.  If the list
     7      * contains multiple elements equal to the specified object, there is no
     8      * guarantee which one will be found.
     9      *
    10      * <p>This method runs in log(n) time for a "random access" list (which
    11      * provides near-constant-time positional access).  If the specified list
    12      * does not implement the {@link RandomAccess} interface and is large,
    13      * this method will do an iterator-based binary search that performs
    14      * O(n) link traversals and O(log n) element comparisons.
    15      *
    16      * @param  list the list to be searched.
    17      * @param  key the key to be searched for.
    18      * @return the index of the search key, if it is contained in the list;
    19      *           otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
    20      *           <i>insertion point</i> is defined as the point at which the
    21      *           key would be inserted into the list: the index of the first
    22      *           element greater than the key, or <tt>list.size()</tt> if all
    23      *           elements in the list are less than the specified key.  Note
    24      *           that this guarantees that the return value will be &gt;= 0 if
    25      *           and only if the key is found.
    26      * @throws ClassCastException if the list contains elements that are not
    27      *           <i>mutually comparable</i> (for example, strings and
    28      *           integers), or the search key is not mutually comparable
    29      *           with the elements of the list.
    30      */
    31 
    32 private static final int BINARYSEARCH_THRESHOLD   = 5000;//二分查找的阈值
    33 
    34 public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) {
    35     if(list instanceof RandomAccess || list.size() < BINARYSEARCH_THRESHOLD)//RandomAccess,是一个接口,用来标记一个list是支持高性能随机访问的
    36         return Collections.indexedBinarySearch(list, key);
    37     else
    38         return Collections.iteratorBinarySearch(list, key);
    39 }
    40 
    41 private static <T> int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
    42     int low = 0;
    43     int high = list.size() - 1;
    44     while(low <= high) {
    45         int mid = (low + high) >>> 1;//>>> 无符号右移,空位补0;右移一位,相当于除以2,但右移的运算速度更快,若使用(low+high)/2求中间位置容易溢出
    46         Comparable<? super T> midVal = list.get(mid);
    47         int cmp = midVal.compareTo(key);
    48         
    49         if(cmp < 0)            
    50             low = mid + 1;
    51         else if(cmp > 0)
    52             high = mid - 1;
    53         else
    54             return mid;//key found
    55     }
    56     return  -(low + 1);//key not found
    57 }
    58 
    59 private static <T> int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key) {
    60     int low = 0;
    61     int high = list.size() - 1;
    62     ListIterator<? extends Comparable<? super T>> i = list.listInterator();
    63     while (low <= high) {
    64         int mid = (low + high) >>> 1;
    65         Comparable<? super T> midVal = get(i, mid);
    66         int cmp = midVal.compareTo(key);
    67         
    68         if(cmp < 0) {
    69             low = mid + 1;
    70         } else if(cmp > 0) {
    71             high = mid - 1;
    72         } else {
    73             return mid;// key found
    74         }
    75     }
    76     return -(low + 1);// key not found        
    77 }

    注:

    (1)list需先按照升序排好;

    (2)如果list中有重复的元素,结果是不确定的;

    (3)List<? extends Comparable<? super T>>,java泛型,<? extends T> 表示类型的上界,表示参数的类型的可能是T或是T的子类;<? super T> 表示类型的下界,表示参数的类型是此类型T的父类型,直至Object;

  • 相关阅读:
    C#操作LX3600非接触式IC卡读写器
    jquery easyui datagrid 动态改变url地址中的参数值
    给javascript添加事件
    解决远程连接mysql很慢的问题(mysql_connect 打开连接慢)
    not in和not exists的区别
    sql中case when then的用法
    SQL查询重复数据
    SQL 批量添加的语法
    SQL函数和存储过程的区别
    SQL type in 语法
  • 原文地址:https://www.cnblogs.com/lemon-now/p/5112277.html
Copyright © 2020-2023  润新知