二分查找:又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。时间复杂度O(h)=O(log2n)。
算法思想:首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
public class BinarySearch {
public static void main(String[] args) {
int arr[] = { 3, 5, 11, 17, 21, 23, 28, 30, 32, 50, 64, 78, 81, 95, 101 };
// int result = binarySearchRecursion(arr, 0, arr.length - 1, 78);
int result = binarySearchCycle(arr, 64);
System.out.println(result);
}
/**
* 递归实现
*
* @param arr
* @param start
* @param end
* @param key
* @return
*/
private static int binarySearchRecursion(int[] arr, int start, int end,
int key) {
if (start > end) {
return -1;
}
// 取中间标记
int mid = (end - start) / 2 + start;
if (arr[mid] == key) {// 查找到key值,返回查找到的值
return arr[mid];
} else if (arr[mid] > key) {// 当中间值大于key值,递归从前半部分查找
return binarySearchRecursion(arr, start, mid - 1, key);
} else if (arr[mid] < key) {// 当中间值小于key值,递归从后半部分查找
return binarySearchRecursion(arr, mid + 1, end, key);
}
return -1;
}
/**
* 循环实现
*
* @param arr
* @param key
* @return
*/
private static int binarySearchCycle(int[] arr, int key) {
// 取中间标记
int mid = arr.length / 2;
// 查找到key值,返回查找到的值
if (arr[mid] == key) {
return arr[mid];
}
// 设置开始和结束标识
int start = 0;
int end = arr.length - 1;
while (start <= end) {
mid = (end - start) / 2 + start;
if (arr[mid] > key) {// 当中间值大于key值,递归从前半部分查找
end = mid - 1;
} else if (arr[mid] < key) {// 当中间值小于key值,递归从后半部分查找
start = mid + 1;
} else {
return arr[mid];
}
}
return -1;
}
}