package com.learn.tree.demo2;
/**
* 二分查找法( binary search) 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好,占用系统内存较少; * 其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。 * 首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功; * 否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表, * 否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。 * * 二分查找法——时间复杂度可以表示O(h)=O(log2n),远优于一般查找时间复杂度O(n) */public class BinarySearch { /** * 二分查找法 -迭代法 * * @param value * @param arr(默认为升序) * @return */ public static int binarySearch(int value, int[] arr) { int left = 0; int right = arr.length - 1;;// 这里是使用一个迭代算法实现 二分查找法 [l,r]这个区间是一个左闭右闭 的区间 while (left <= right) { // int m=(l+r)/2;这种写法bug ,当l和r都接近无求大时会造成 越界(如果为降序相反)int middle = left + (right - left) / 2
// 该数组默认为升序 如果要查找的值大于指定的值 数组向右切割 if (value > arr[middle]) { left = middle + 1;} // 该数组默认为降序 如果要查找的值小于指定的值 数组向左切割(如果为降序相反) else if (value < arr[middle]) { right = middle - 1;
} else { return middle; }
}
// 该数组中没有搜索到 就返回下标-1 return -1; }/**
* 二分查找法-递归法 * * @param arr(该数组默认为升序) * @param value * @return */ public static int binarySearch(int[] arr, int value) { int left = 0; int right = arr.length - 1; // int m=(l+r)/2;这种写法bug ,当l和r都接近无求大时会造成 越界(如果为降序相反) int key = binarySearch(arr, left, right, value); return key; }/**
* 二分法查找法内部实现法 */ private static int binarySearch(int[] arr, int left, int right, int value) { // 该数组中没有搜索到 就返回下标 -1 if (left >=right)//递归结束条件 return -1; // 这里是使用一个迭代算法实现 二分查找法 [l,r]这个区间是一个左闭右闭 的区间 int middle = left + (right - left) / 2; if (value > arr[middle]) { // 数组向右平移 left = middle + 1; return binarySearch(arr, left, right, value); } else if (value < arr[middle]) { // 数组向左平移 right = middle - 1; return binarySearch(arr, left, right, value); } else { return middle; } }public static void main(String[] args) {
int[] arr = { 1, 3, 4, 5, 9, 11, 12, 17, 19, 23, 24, 34, 88, 99, 121, 123, 134, 167, 222, 333, 444, 555, 666 }; System.out.println("12在数组arr中的下标:" + binarySearch(12, arr)); System.out.println("12在数组arr中的下标:" + binarySearch(arr, 12)); }}