- 前提条件:队列是有序的
- 不计算排序时间的话时间复杂度是O(logn),计算排序时间的话复杂度变为O(nlogn)
- 应用:多次查找
递归实现二分查找法
public static <E extends Comparable<E>> int search(E[] data,E target){return search(data,0, data.length,target);}private static <E extends Comparable<E>> int search(E[] data,int l ,int r, E target){if (l>r) return -1;int mid = l+(r-l)/2;if (data[mid].compareTo(target) == 0) return mid;if (data[mid].compareTo(target) < 0){search(data,mid+1,r,target);}return search(data,0,mid-1,target); //if (data[mid].compareTo(target) > 0)}
非递归实现二分查找法
public static <E extends Comparable<E>> int searchR(E[] data,E target){int l = 0, r = data.length-1;while (l <=r ){int mid = l+(r-l)/2;if (data[mid].compareTo(target) == 0)return mid;else if (data[mid].compareTo(target) < 0 )l = mid+1;elser = mid-1;}return -1;}
修改循环不变量的定义之后
定义:在[l,r)的范围里面查找target
首先左边界
L原来是data.length-1,现在应该是data.lengthpublic static <E extends Comparable<E>> int searchR2(E[] data,E target){int l = 0, r = data.length;while (l < r ){int mid = l+(r-l)/2;if (data[mid].compareTo(target) == 0)return mid;else if (data[mid].compareTo(target) < 0 )l = mid+1; //继续在data[mid+1,r)范围里寻找解elser = mid ; //继续在data[l,mid)范围里寻找解}return -1;}
二分查找法的变种
查找大于target的最小值
关键部分的代码:
if(arr[mid] > target) r = midif(arr[mid] < target) l = mid + 1
public static <E extends Comparable<E>> int upper(E[] data,E target){int l = 0, r = data.length;while (l < r ){int mid = l+(r-l)/2;if (data[mid].compareTo(target) <= 0 )l = mid+1;elser = mid ; // 之所以r != mid -1 是因为该target可能就是最小值}return l;}
举一个例子
另一个变种ceil
定义
定义(>=target的最小索引)
- 如果数组中存在元素,返回最小索引
- 如果数组中不存在元素,返回upper
```java
public static
> int lower_ceil(E[] data,E target){
int l = 0, r = data.length;while (l < r ){int mid = l+(r-l)/2;if (data[mid].compareTo(target) < 0 )l = mid+1;elser = mid ;}return l;}
<a name="kOHUw"></a>## lower- 查找小于target的最大值```javapublic static <E extends Comparable<E>> int lower(E[] data,E target){int l = -1, r = data.length-1;while (l < r ){int mid = l+(r-l+1)/2; //需要向上取整(大坑)if (data[mid].compareTo(target) < 0 )l = mid;elser = mid-1 ;}return l;}
作业
- Select K 在arr[l,r)的范围中寻找k小元素
- 归并排序
