来源:
Java编程的逻辑
集合类关系:
1 相关方法
1.1 针对List接口的二分查找
//一个要求List的每个元素实现Comparable接口,另一个不需要,但要求提供Comparator。
public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) {
//如果List可以随机访问(如数组),即实现了RandomAccess接口,或者元素个数比较少,那么实现思路与Arrays一样,调用indexedBinarySearch根据索引直接访问中间元素进行查找
if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
return Collections.indexedBinarySearch(list, key);
//否则调用iteratorBinarySearch使用迭代器的方式访问中间元素进行查找
else
return Collections.iteratorBinarySearch(list, key);
}
//O(log2(N))
private static <T> int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
int low = 0;
int high = list.size()-1;
while (low <= high) {
int mid = (low + high) >>> 1;
Comparable<? super T> midVal = list.get(mid);//访问中间元素
int cmp = midVal.compareTo(key);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found
}
//通过迭代器方法逐个移动到期望的位置
//比较的次数为O(log2(N)),但遍历移动的次数为O(N),N为列表长度
private static <T> int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key){
int low = 0;
int high = list.size()-1;
ListIterator<? extends Comparable<? super T>> i = list.listIterator();
while (low <= high) {
int mid = (low + high) >>> 1;
Comparable<? super T> midVal = get(i, mid);//寻找中间元素
int cmp = midVal.compareTo(key);
if (cmp < 0)
low = mid + 1;
else if (cmp