二分查找(递归形式)
二分查找(非递归形式)**
lower: 找比target小的 最大值
lower_floor : 找到target在数组中最小的索引 没有则返回lower
upper_floor: 找到target在数组中最大的索引 没有则返回lower
upper: 找比target大的 最小值
upper_Ceil: 找target在数组中最大的索引 如果没有则输出其upper值
lower_ceil : 找target在数组中最小的索引 如果没有则输出upper值
public class BinarySearch {
private BinarySearch() {}
// 非递归实现
public static int search(int[] arr, int target) {
return search(arr, target, 0, arr.length-1);
}
private static int search(int[] arr, int target, int l, int r) {
while (l <= r) {
int mid = l + (r-l)/2;
if (arr[mid] == target)
return mid;
else if (arr[mid] < target) {
l = mid+1;
} else {
r = mid-1;
}
}
return -1;
}
// 递归实现
public static int searchR(int[] arr, int target) {
return searchR(arr, target, 0, arr.length-1);
}
private static int searchR(int[] arr, int target, int l, int r) {
if (l > r)
return -1;
int mid = l + (r-l)/2;
if (arr[mid] == target)
return mid;
if (arr[mid] > target)
return searchR(arr, target, l, mid-1);
return searchR(arr, target, mid+1, r);
}
// 使用lower_ceil 实现二分查找
public static int lowerCeilSearch(int[] data, int target) {
int l = 0, r = data.length;
while (l < r) {
int mid = l + (r - l) / 2;
if (data[mid] < target) {
l = mid + 1;
} else {
r = mid;
}
}
if (l < data.length && data[l] == target)
return l;
return -1;
}
// lower : 找到比target 小的 最大值
public static int lower(int[] data, int target) {
int l = -1, r = data.length-1;
while (l < r) {
int mid = l + (r-l+1) /2;
if (data[mid] < target) {
l = mid;
} else {
r = mid-1;
}
}
return l;
}
// lower_floor : 找到最小的target索引 没有则返回lower
public static int lowerFloor(int[] data, int target) {
int p = lower(data, target);
if (p+1 < data.length && data[p+1] == target)
return p+1;
else
return p;
}
// upper_floor
// <= target 的 最大索引
public static int upperFloor(int[] data, int target) {
int l = -1, r = data.length-1;
while (l < r) {
int mid = l + (r-l+1)/2;
if (data[mid] > target) {
r = mid -1;
} else {
l = mid;
}
}
return l;
}
// upper : 找比target 大的 最小值
public static int upper(int[] data, int target) {
int l = 0, r = data.length;
while (l < r) {
int mid = l + (r-l)/2;
if (data[mid] <= target) {
l = mid + 1;
} else {
r = mid;
}
}
return l;
}
// upper_Ceil: 找target在数组中最大的索引 如果没有则输出其upper值
public static int upperCeil(int[] data, int target) {
int p = upper(data, target);
if (p-1 >= 0 && data[p-1] == target) {
return p-1;
}
return p;
}
// >= target 的最小值
// lower_ceil : 找target在数组中最小的索引 如果没有则输出upper值
public static int lowerCeil(int[] data, int target) {
int l = 0, r = data.length;
while (l < r) {
int mid = l + (r-l)/2;
if (data[mid] < target) {
l = mid+1;
} else {
r = mid;
}
}
return l;
}
public static void main(String[] args) {
int[] arr = {1, 1, 3, 3, 5, 5};
for (int i = 0; i <= 6; i++) {
System.out.print(lowerFloor(arr, i) + " ");
}
System.out.println();
for (int i = 0; i <= 6; i++) {
System.out.print(upperFloor(arr, i) + " ");
}
System.out.println();
}
}