二分查找是一个较为简单的查找算法.要求所查数据集合必须为有序的.也因此,注定了这种数据结构在插入方面的xing性能很差(因为要移动引用位置,腾出空间来,在javali里面,由于数据存的是引用.所以影响不大);
具体思路是: 在一个有序集合中,确定中间位置的值middleIndex位置.然后这个位置的值和要查询的目标target进行比较, 如果小于target,说明middleIndex位置左边的数都小于target.那么将开始位置的下标设置为middleIndex. 即startIndex=middleIndex; 然后再来根据新的startIndex和endIndex算出一个新的middleIndex值. 如果target小于middleIndex位置的值.说明middleIndex右边的数都是大于target的.那么将endIndex设置为middleIndex. 重复上面的操作, 直到2者相等或者startIndex=endIndex...
然后补充下上面逻辑会漏掉的情况,就是集合里面只有一个数的情况. 这种情况下单独抽离出来;
-------------------------------------------------
上面那种查找针对的是集合里面不会有重复数据的情况. 如果有重复数据, 那么在第一次找到target的时候, 后面继续用二分查找很不划算(因为在有序集合中,相同的数一定是相邻的), 所以这种情况下, 只需将middleIndex -1 或者middleIndex + 1就可以了;同时,这种方法还不会重复查找已经找到过的数据.
public void binarySearch() {
// int[] a = new int[] {1,2,3,7,7,7,7,8,9};
int[] a = new int[]{7,7,7,7,7,7,7,7,7,7};
int target = 7;
int startIndex = 0;
int endIndex = a.length - 1;
int middleIndex = (startIndex + endIndex) / 2;
/** 重复值查询逻辑*/
int lowIndex = 0;
int upperIndex = 0;
while (startIndex < endIndex && startIndex < middleIndex) {
if (target > a[middleIndex]) {
startIndex = middleIndex;
middleIndex = (startIndex + endIndex) / 2;
} else if (target < a[middleIndex]) {
endIndex = middleIndex;
middleIndex = (startIndex + endIndex) / 2;
} else {
System.out.println(middleIndex);
/** 有重复值查询逻辑*/
lowIndex = middleIndex;
upperIndex = middleIndex;
while (startIndex <= middleIndex - 1) {
middleIndex = middleIndex - 1;
if (target == a[middleIndex]) {
System.out.println(middleIndex);
}
}
middleIndex = upperIndex;
while (endIndex >= middleIndex + 1) {
middleIndex = middleIndex + 1;
if (target == a[middleIndex]) {
System.out.println(middleIndex);
}
}
return;
}
}
/** 只有一个数的情况*/
if (target == a[middleIndex]) {
System.out.println(middleIndex);
}
}