一维数组的二分查找:
class Range {
// 属性,区间的上限下标 + 区间的下限下标
// 这里选用左闭右闭
private final long[] array;
private int lowIndex;
private int highIndex;
// 区间 array[lowIndex, highIndex]
public Range(long[] array) {
this.array = array;
this.lowIndex = 0;
this.highIndex = array.length - 1;
}
public int size() {
return highIndex - lowIndex + 1;
}
public long getMiddleValue() {
return array[getMiddleIndex()];
}
public int getMiddleIndex() {
return (lowIndex + highIndex) / 2;
}
public void discardRightPart() {
highIndex = getMiddleIndex() - 1;
}
public void discardLeftPart() {
lowIndex = getMiddleIndex() + 1;
}
}
public class BinarySearch {
// 二分查找,不需要一个 BinarySearch 对象
// 所以,可以用 static,可以不用
public static int binarySearch(long[] array, long target) {
Range range = new Range(array); // 把数组抽象成区间对象
while (range.size() > 0) {
long middleValue = range.getMiddleValue();
if (target == middleValue) {
return range.getMiddleIndex();
} else if (target < middleValue) {
range.discardRightPart();
} else {
range.discardLeftPart();
}
}
return -1;
}
public static void main(String[] args) {
long[] array = {
1, 2, 3, 4, 5, 6, 7};
System.out.println(binarySearch(array, 1));
}
}
二维数组的二分查找:
目录结构:
Search.java
package binary_search;
/**
* @ClassName Search
* @Description :TODO
* @Author Josvin
* @Date 2021/01/24/16:57
*/
public class Search {
// new int[] { 0, 3 }
public static int[] search(long[][] array, int rows, int columns, long target) {
Range range = new Range(array, rows, columns);
while (range.size() > 0) {
long middleValue = range.getMiddleValue();
if (target == middleValue) {
return range.getMiddleIndex();
} else if (target < middleValue) {
range.discardRightPart();
} else {
range.discardLeftPart();
}
}
// 只要返回特殊值表示没有找到即可
return new int[] {
-1, -1 };
// return null;
}
}
Range.java
元素个数计算:
中间下标计算:
package binary_search;
/**
* @ClassName Range
* @Description :TODO
* @Author Josvin
* @Date 2021/01/24/16:58
*/
public class Range {
private final long[][] array;
private final int columns;
private int lowRow;
private int lowColumn;
private int highRow;
private int highColumn;
public Range(long[][] array, int rows, int columns) {
this.array = array;
this.columns = columns;
this.lowRow = 0;
this.lowColumn = 0;
this.highRow = rows - 1;
this.highColumn = columns - 1;
}
public int size() {
return (columns - lowColumn) + ((highRow - lowRow - 1) * columns) + (highColumn + 1);
}
public long getMiddleValue() {
int[] index = getMiddleIndex();
int row = index[0];
int column = index[1];
return array[row][column];
}
public int[] getMiddleIndex() {
int halfSize = size() / 2;
int middleRow = lowRow;
int middleColumn = lowColumn;
middleColumn += halfSize;
// middleColumn 还不是一个合法下标
while (middleColumn >= columns) {
middleRow++;
middleColumn -= columns;
}
return new int[] {
middleRow, middleColumn };
}
public void discardRightPart() {
// 让 high 往左走,不包括 middle 位置
int[] index = getMiddleIndex();
int row = index[0];
int column = index[1];
highRow = row;
highColumn = column - 1; // 不要中间位置
if (highColumn < 0) {
highRow--;
highColumn = columns - 1;
}
}
public void discardLeftPart() {
// 让 low 往右做,不包括 middle 位置
int[] index = getMiddleIndex();
int row = index[0];
int column = index[1];
lowRow = row;
lowColumn = column + 1; // 不要中间位置
if (lowColumn >= columns) {
lowRow++;
lowColumn = 0;
}
}
}
Test.java
package binary_search;
import java.util.Arrays;
/**
* @ClassName Test
* @Description :TODO
* @Author Josvin
* @Date 2021/01/24/16:58
*/
public class Test {
public static void main(String[] args) {
long[][] array = {
{
1, 2, 3, 4, 5},
{
6, 7, 8, 9, 10},
{
11, 12, 13, 14, 15}
};
int rows = 3;
int columns = 5;
for (long target = 0; target <= 16; target++) {
int[] index = Search.search(array, rows, columns, target);
System.out.printf("查找 %d 的结果是: %s\n", target, Arrays.toString(index));
}
}
}