二分查找
/**
* 时间复杂度:O(nlogn)
* 空间复杂度:O(1)
* 二分查找使用限制:
* ⾸先,⼆分查找依赖的是顺序表结构,简单点说就是数组
* 其次,⼆分查找针对的是有序数据。
* 再次,数据量太⼩不适合⼆分查找。
* 最后,数据量太⼤也不适合⼆分查找。因为数组要申请连续空间
*
* ⼆分查找更适合⽤在“近似”查找问题
* @author Administrator
*
*/
public class BinarySearch {
public static void main(String[] args) {
int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// System.out.println(bsearch(array,7,0,array.length));
// System.out.println(bsearch2(array,7,0,array.length));
int[] arr2 = new int[] { 1, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 9, 10 };
// System.out.println(bsearchFirst(arr2,7,0,arr2.length));
// System.out.println(bsearchLast(arr2,7,0,arr2.length));
// System.out.println(bsearchFirstBig(arr2,3,0,arr2.length));
System.out.println(bsearchFirstSmall(arr2, 7, 0, arr2.length));
}
//循环查找给定值key
public static int bsearch(int[] arr, int key, int low, int high) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == key) {
return mid;
} else if (arr[mid] > key) {
high = mid - 1;
} else if (arr[mid] < key) {
low = mid + 1;
}
}
return -1;
}
//递归查找给定值key
public static int bsearch2(int[] arr, int key, int low, int high) {
if (low >= high)
return -1;
int mid = low + (high - low) / 2;
if (arr[mid] == key) {
return mid;
} else if (low >= high) {// 没有找到
return -1;
} else {
if (arr[mid] > key) {
return bsearch2(arr, key, low, mid - 1);
} else if (arr[mid] < key) {
return bsearch2(arr, key, mid + 1, high);
}
}
return -1;
}
// 查找第一个等于key值
public static int bsearchFirst(int[] arr, int key, int low, int high) {
if (low > high)
return -1;
int mid = low + (high - low) / 2;
if (arr[mid] > key) {
return bsearchFirst(arr, key, low, mid - 1);
} else if (arr[mid] < key) {
return bsearchFirst(arr, key, mid + 1, high);
} else {
if (mid == 0 || arr[mid - 1] != key) {
return mid;
} else {
return bsearchFirst(arr, key, low, mid - 1);
}
}
}
// 查找最后一个等于key值
public static int bsearchLast(int[] arr, int key, int low, int high) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] > key) {
high = mid - 1;
} else if (arr[mid] < key) {
low = mid + 1;
} else {
if (mid == (arr.length - 1) || arr[mid + 1] != key) {
return mid;
} else {
low = mid + 1;
}
}
}
return -1;
}
// 查找第一个大于key值
public static int bsearchFirstBig(int[] arr, int key, int low, int high) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (key < arr[mid]) {
if (mid == arr.length - 1 || arr[mid - 1] <= key) {
return mid;
} else {
high = mid - 1;
}
} else if (key >= arr[mid]) {
low = mid + 1;
}
}
return -1;
}
// 查找第一个小于key值
public static int bsearchFirstSmall(int[] arr, int key, int low, int high) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] >= key) {
high = mid - 1;
}
if (arr[mid] < key) {
if (mid == 0 || arr[mid + 1] >= key) {
return mid;
} else {
low = mid + 1;
}
}
}
return -1;
}
}