// 二分查找函数(递归实现) intbinarySearchRecursive(int a[], int left, int right, int x) { if (left > right) { return-1; // 未找到目标值 } int mid = left + (right - left) / 2; // 计算中间位置,避免整数溢出 if (a[mid] == x) { return mid; // 找到目标值 } elseif (a[mid] > x) { returnbinarySearchRecursive(a, left, mid - 1, x); // 在左半部分查找 } else { returnbinarySearchRecursive(a, mid + 1, right, x); // 在右半部分查找 } }
// 二分查找函数(非递归实现) intbinarySearchIterative(int a[], int n, int x) { int left = 0; int right = n - 1; while (left <= right) { int mid = left + (right - left) / 2; // 计算中间位置,避免整数溢出 if (a[mid] == x) { return mid; // 找到目标值 } elseif (a[mid] > x) { right = mid - 1; // 在左半部分查找 } else { left = mid + 1; // 在右半部分查找 } } return-1; // 未找到目标值 }
intmain() { int n; cin >> n; int a[n]; for (int i = 0; i < n; i++) { cin >> a[i]; } int x; cin >> x; // 调用非递归版本的二分查找函数 int result = binarySearchIterative(a, n, x); // 如果要使用递归版本,可以取消下面这行的注释,并注释掉上面这行 // int result = binarySearchRecursive(a, 0, n - 1, x); cout << result << endl; return0; }
时间复杂度
时间复杂度:O(logn),其中 n 为数组的长度。
空间复杂度:O(1)(非递归实现)或 O(logn)(递归实现,由递归调用栈占用的空间)。
代码解释
二分查找的核心思想是将目标值与数组中间的元素进行比较,并根据比较结果缩小查找范围。
在这个实现中,我们提供了两种版本的二分查找:递归版本和非递归版本。
递归版本的终止条件是左边界大于右边界(表示未找到目标值)或者找到目标值。
非递归版本使用循环来代替递归,循环的条件是左边界小于等于右边界。
在计算中间位置时,我们使用 mid = left + (right - left) / 2 而不是 mid = (left + right) / 2,这是为了避免在 left 和 right 很大时发生整数溢出。