折半查找是在有序表中,把待查找数据值与查找范围的中间元素值进行比较,会有三种情况出现:
- 待查找数据值与中间元素值正好相等,则放回中间元素值的索引。
- 待查找数据值比中间元素值小,则以整个查找范围的前半部分作为新的查找范围,执行1),直到找到相等的值。
- 待查找数据值比中间元素值大,则以整个查找范围的后半部分作为新的查找范围,执行1),直到找到相等的值
- 如果最后找不到相等的值,则返回不存储数据的备用单位0。
给你的问题是,标准输入一升序排列有序整数表,使用折半查找方法查找一个给定的整数值,查找中是通过使用表中的元素与给定的元素值进行比较完成查找,需要你依次输出在折半查找过程中使用过比较的元素值。
输入:标准输入,输入的第一行为一个正整数n,表示需要查找表的元素个数;第二行为具有升序序列的n个整数,两数之间为一个空格隔开;第三行为需要你查找的整数。
输出:标准输出,第一行依次输出在查找过程中进行比较的元素值,两数之间使用一个空格隔开。输出的第二行输出查找结果,如果查找元素在表中,输出该元素的序号(从1开始编号),如果查找元素不在表中,输出“NO"。
输入样例:
13
7 14 18 21 23 29 31 35 38 42 46 49 52
21
输出样例:
31 18 23 21
4
第一种写法
import java.util.ArrayList;
import java.util.Scanner;
class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n + 1];
for (int i = 1; i <= n; i++) {
a[i] = sc.nextInt();
}
ArrayList arr = new ArrayList<>();
int x = sc.nextInt();
// 二分查找
int l = 1, r = n;
while (l <= r) {
int mid = (l + r) >> 1;
arr.add(a[mid]);
if (x > a[mid]) {
l = mid + 1;
} else if (x < a[mid]) {
r = mid - 1;
} else {
break;
}
}
for (int i = 0; i < arr.size(); i++) {
if (i > 0) System.out.print(" ");
System.out.print(arr.get(i));
}
System.out.println();
if (l <= r) {
System.out.println((l + r) >> 1);
} else {
System.out.println("NO");
}
}
}
第二种写法
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n + 1];
for (int i = 1; i <= n; i++) {
arr[i] = sc.nextInt();
}
int quest = sc.nextInt();
boolean flag = false;
int l = 1, r = n, mid = 1;
while (l <= r) {
mid = (r + l) / 2;
if (arr[mid] == quest) {
flag = true;
break;
} else if (arr[mid] < quest) {
l = mid + 1;
} else {
r = mid - 1;
}
System.out.print(arr[mid] + " ");
}
if (flag) {
System.out.println(arr[mid] + "\n" + mid);
} else {
System.out.println("\nNO");
}
}
}