1.普通的二分查找
二分查找的关键是为了确定上下界,必须注意边界,全开,全闭,半开半闭,统一就好
public static int search(int[] a, int key, int low, int hight) {
int middle;
while (low <= hight) {
middle = ((hight - low) >> 1) + low;// 一定要加括号啊
if (key == a[middle]) {
return middle;
} else if (key > a[middle]) {
low = middle + 1;
} else {
hight = middle - 1;
}
}
return -1;
}
2. 具有偏移的二分查找
比如:4,7,8,9,10,1,2,3
在循环递增数组中我们不能简单地通过与数组中间元素的大小关系来确定要检索的元素所落在的区间范围。
要确定范围我们可以再加上要检索的元素与数组两端的元素的大小关系。 循环递增数组有这么一个性质
以数组中间元素将循环递增数组划分为两部分则一部分为一个严格递增数组
而另一部分为一个更小的循环递增数组。当中间元素大于首元素时前半部分为严格递增数组后半部分为循环递增数组当中间元素小于首元素时前半部分为循环递增数组后半部分为严格递增数组。 记要检索的元素为key数组的首元素为a[low]
中间元素为a[mid]末尾元素为a[high]。则当key不等于a[mid] 时
1、a[mid] > a[low]即数组前半部分为严格递增数组后半部分为循环递增数组时若key小于a[mid]并且不小于a[low]时则key落在数组前半部分否则key落在数组后半部分。
2、a[mid] < a[high]即数组前半部分为循环递增数组后半部分为严格递增数组时若key大于a[mid]并且不大于a[high]时则key落在数组后半部分否则key落在数组前半部分。
public static int search(int[] a, int key) {
int low = 0;
int hight = a.length - 1;
int middle = 0;
int pos = -1;// -1表示没有查找到
while (low <= hight) {
System.out.println("low"+low);
System.out.println("hight"+hight);
middle = ((hight - low) >> 1) + low;
System.out.println("middle:"+middle);
if (key == a[middle]) {
pos = middle;
break;
}
if (a[middle] > a[low]) {// 前半部分是递增的
if (key > a[low] && key < a[middle]) {
hight = middle - 1;
} else {
low = middle + 1;
}
} else {
if (key > a[middle] && key < a[hight]) {
low = middle + 1;
} else {
hight = middle - 1;
}
}
}
return pos;
}