import java.util.Arrays;

/**
* 二分查找
* <p>
* 首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;
* 否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。
* 重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功
*/
public class BinarySearch {

public static void main(String[] args) {
// 测试次数
int times = 500000;

int maxNum = 100;
int maxSize = 100;
for (int i = 0; i < times; i++) {
// 生成随机数组
int[] arr = generateArray(maxNum, maxSize);
// 排序
Arrays.sort(arr);
// 比较查找结果
if (binarySearch(arr, 50) != arrayContains(arr, 50)) {
System.out.println("Sort failed!!!");
System.out.println(binarySearch(arr, 50));
System.out.println(arrayContains(arr, 50));
System.out.println(Arrays.toString(arr));
return;
}
}
System.out.println("Sort success");
}

/**
* 数组是否包含给定数值
*
* @param arr 数组
* @param key 给定数值
* @return 是否包含
*/
private static boolean arrayContains(int[] arr, int key) {
if (arr == null || arr.length == 0) {
return false;
}
for (int value : arr) {
if (value == key) {
return true;
}
}
return false;
}

/**
* 二分查找
*
* @param arr 数组
* @param key 给定数值
* @return 是否包含
*/
private static boolean binarySearch(int[] arr, int key) {
if (arr == null || arr.length == 0) {
return false;
}
int left = 0;
int mid = 0;
int right = arr.length - 1;

// 第一种写法
while (left < right) {
mid = left + ((right - left) >> 1);
if (arr[mid] == key) {
return true;
} else if (arr[mid] > key) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return arr[left] == key;

// 第二种写法
// while (left <= right) {
// mid = left + ((right - left) >> 1);
// if (arr[mid] == key) {
// return true;
// } else if (arr[mid] > key) {
// right = mid - 1;
// } else {
// left = mid + 1;
// }
// }
// return false;
}

/**
* 生成随机数组
*
* @param maxNum 最大数
* @param maxSize 数组最大大小
* @return 随机数组
*/
private static int[] generateArray(int maxNum, int maxSize) {
int[] arr = new int[(int) (maxSize * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (maxNum * Math.random()) - (int) (maxNum * Math.random());
}
return arr;
}

}