一维数组
首先我们关注点就需要分离,我们只需要考虑需要用什么,而不需要考虑他如何去实现,我们先写出二分查找的逻辑:当查找一维数组的时候,如果找到了,就返回下标,如果未找到,返回-1;
然后我们将区间抽象出来:
然后具体实现区间:
代码:
class Range {
private final int[] array;
private int left;
private int right;
public Range(int[] array) {
this.array = array;
this.left = 0;
this.right = array.length - 1;
}
public int size() {
return right - left + 1;
}
//中间元素的值
public int getMidValue() {
return array[getMidIndex()];
}
//中间元素的下标
public int getMidIndex() {
return (left + right) / 2;
}
public void discardLeftPart() {
left = getMidIndex() + 1;
}
public void discardRightPart() {
right = getMidIndex() - 1;
}
}
public class BinarySearch {
public static int binarySearch(int[] array, int target) {
//将数组抽象成区间对象
Range range = new Range(array);
//当区间还有数时,查找还得继续
while (range.size() > 0) {
//获取中间元素
int midValue = range.getMidValue();
if (midValue == target) {
return range.getMidIndex();
} else if (midValue < target) {
//丢掉左半边
range.discardLeftPart();
} else {
//丢掉右半边
range.discardRightPart();
}
}
return -1;
}
}
/**
* 二分查找的测试
*/
public class BinarySearchTest {
public static void main(String[] args) {
int[] arr = {
1, 2, 3, 4, 5, 6, 7, 8, 9};
int a = BinarySearch.binarySearch(arr, 5);
System.out.println(a);
}
}
具体结果:
二维数组
解法1:
将二维数组转换为一维数组:
主要思想和上面一样,我们将二维数组,首先转换为一维数组,然后在实现二分查找:返回其一维数组下标:即在二维数组中是第几个元素。
代码:
import java.util.Arrays;
/**
*二维数组的二分查找实现
*/
class Range1 {
private final int[][] array;
private int left;
private int right;
private int[]arr;
public Range1(int[][] array, int m, int n) {
//二维数组转换为一维数组
int[] arr= new int[m*n];
int index = 0;
for (int[] a : array) {
for (int element : a) {
arr[index++] = element;
}
}
// System.out.println(Arrays.toString(arr));
this.array = array;
this.arr=arr;
this.left = 0;
this.right = arr.length-1;
}
public int size() {
return right - left + 1;
}
//中间元素的值
public int getMidValue() {
return arr[getMidIndex()];
}
//中间元素的下标
public int getMidIndex() {
return (left + right) / 2;
}
public void discardLeftPart() {
left = getMidIndex() + 1;
}
public void discardRightPart() {
right = getMidIndex() - 1;
}
}
public class BinarySearch2 {
public static int binarySearch2(int[][] array, int m, int n, int target) {
Range1 range1 = new Range1(array, m, n);
while (range1.size() > 0) {
int midValue = range1.getMidValue();
if (midValue == target) {
return range1.getMidIndex();
} else if (midValue < target) {
range1.discardLeftPart();
} else {
range1.discardRightPart();
}
}
return -1;
}
}
/**
* 二分查找的测试
*/
public class BinarySearchTest {
public static void main(String[] args) {
int[] arr = {
1, 2, 3, 4, 5, 6, 7, 8, 9};
int a = BinarySearch.binarySearch(arr, 5);
System.out.println(a);
}
}
具体结果:
解法2:
利用将区间抽象出来,用面向对象的思维求解:
代码:
package binary_Serch;
/**
* 二维数组的二分查找
*/
public class binary_Search {
//返回一个下标放在一维数组中
public static int[] search(int[][] array, int rows, int columns, long target) {
Range range = new Range(array, rows, columns);
while (range.size() > 0) {
int middleValue = range.getMiddleValue();
if (target == middleValue) {
return range.getMiddleIndex();
} else if (target < middleValue) {
range.discardRightPart();
} else {
range.discardLeftPart();
}
}
// 只要返回特殊值表示没有找到即可
return new int[]{
-1, -1};
}
}
package binary_Serch;
/**
* Range 区间
*/
public class Range {
private final int[][] array;
private final int columns;
private int lowRow;
private int lowColumn;
private int highRow;
private int highColumn;
public Range(int[][] 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 int getMiddleValue() {
int[] index = getMiddleIndex();
int row = index[0];
int col = index[1];
return array[row][col];
}
//获取中间元素的下标
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 discardLeftPart() {
int[] index = getMiddleIndex();
int row = index[0];
int col = index[1];
lowRow = row;
lowColumn = col + 1;
if (lowColumn >= columns) {
lowRow++;
lowColumn = 0;
}
}
//丢掉右边
public void discardRightPart() {
int[] index = getMiddleIndex();
int row = index[0];
int col = index[1];
highRow = row;
highColumn = col - 1;
if (highColumn < 0) {
highRow--;
highColumn = columns - 1;
}
}
}
package binary_Serch;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[][] 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 = binary_Search.search(array, rows, columns, target);
System.out.printf("查找 %d 的结果是: %s\n", target, Arrays.toString(index));
}
}
}
具体结果:
ps:还有很多解法,等我学会了继续完善,嘿嘿!