二分查找适用于有序数据,使用前应先将数组按升序或降序排序。其思想如下:
- 设置三个指针 low、high、mid = (high + low)/ 2,分别指向数组最左侧数据、最右侧数据、中间数据。假设待查找关键字为 key
- 若 array[mid] == key,则查找成功,返回元素下标 mid
- 若 array[mid] > key,则 key 在区间 array[low] ~ array[mid - 1] 之间,继续在 array[low] ~ array[mid - 1] 之间使用二分查找法
- 若 array[mid] < key,则 key 在区间 array[mid + 1] ~ array[high] 之间,继续在 array[mid + 1] ~ array[high] 之间使用二分查找法
- 重复步骤 2 ~ 4 ,直至找到结果
public class BinarySearchDemo {
// 非递归二分查找
private static int nonRecursiveBinarySearch(int[] array, int key) {
int high = array.length - 1, low = 0, mid;
while (low <= high) {
mid = low + (high - low) / 2;
if (array[mid] == key) // 若找到,则返回
return mid;
else if (array[mid] > key) // 在左侧查找
high = mid - 1;
else // 在右侧查找
low = mid + 1;
}
return -1;
}
// 递归二分查找
private static int recursiveBinarySearch(int[] array, int low, int high, int key) {
int mid = low + (high - low) / 2;
if (array[mid] == key) // 若找到,则返回
return mid;
else if (array[mid] > key) // 在左侧查找
return recursiveBinarySearch(array, low, mid - 1, key);
else // 在右侧查找
return recursiveBinarySearch(array, mid + 1, high, key);
}
private static void quickSort(int[] array, int left, int right) {
// 数组长度为 0 或 1 时直接退出
if (array == null || left > right || (array.length - 1 <= 0))
return;
int base = array[left]; // base:基准数据
int i = left, j = right;// 让 i 指向数据最左侧,让 j 指向数据最左侧
int temp;
while (i != j) {
// 从右向左搜寻小于 base 的数据
while (array[j] >= base && i < j)
j--;
// 从左向右搜寻大于 base 的数据
while (array[i] <= base && i < j)
i++;
// 交换搜寻到的数据
if (i < j) {
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
// 将基准数放到中间的位置(基准数归位)
array[left] = array[i];
array[i] = base;
/*temp = array[i];
array[i] = array[left];
array[left] = temp;*/
// 一次排序结束,此时 base 左侧的数据全小于 base,右侧的数据全大于base
quickSort(array, left, i - 1);// 快排 base 左侧数据
quickSort(array, i + 1, right);// 快排 base 右侧数据
}
public static void main(String[] args) {
int[] array = new int[] {196, 135, 129, 165, 105, 103, 116, 107, 156,
101, 141, 144, 153, 107, 139, 114, 159, 152, 151, 127};
int len = array.length;
// 1 先将数组变为有序
quickSort(array, 0, len - 1);
System.out.println("数组元素为:");
for (int i = 0; i < len; i++) {
System.out.printf("%d ", array[i]);
}
System.out.println();
int index = -1;
// 2 非递归二分查找
if ((index = nonRecursiveBinarySearch(array, 103)) == -1)
System.out.println("元素不存在!");
else
System.out.printf("非递归二分查找-要查找元素下标为:%d\n", index);
// 3 递归二分查找
if ((index = recursiveBinarySearch(array, 0, len - 1, 151)) == -1)
System.out.println("元素不存在!");
else
System.out.printf("递归二分查找-要查找元素下标为:%d\n", index);
}
}
数组元素为:
101 103 105 107 107 114 116 127 129 135 139 141 144 151 152 153 156 159 165 196
非递归二分查找-要查找元素下标为:1
递归二分查找-要查找元素下标为:13
Process finished with exit code 0