01-复杂度3 二分查找(20 分)

本文介绍如何用C语言实现二分查找算法,适用于处理递增有序的线性表。函数接口定义和样例测试代码提供,帮助理解算法逻辑。

01-复杂度3 二分查找 (20 分)

本题要求实现二分查找算法。

函数接口定义:

Position BinarySearch( List L, ElementType X );

其中List结构定义如下:

typedef int Position;
typedef struct LNode *List;
struct LNode {
   
   
    ElementType Data[MAXSIZE];
    Position Last; /* 保存线性表中最后一个元素的位置 */
};

L是用户传入的一个线性表,其中ElementType元素可以通过>、==、<进行比较,并且题目保证传入的数据是递增有序的。函数BinarySearch要查找XData中的位置,即数组下标(注意:元素从下标1开始存储)。找到则返回下标,否则返回一个特殊的失败标记NotFound

裁判测试程序样例:

#include <stdio.h>
### 二分查找 PTA 填空题及练习 以下是一些与二分查找相关的 PTA 练习题和填空题的示例,涵盖了基本算法实现、边界条件处理以及复杂度析等内容。 --- #### 题目 1:二分查找的基本实现 **题目描述** 输入一个长度为 $ n $ 的非降序排列数组和目标值 $ x $。使用二分查找算法查找 $ x $,如果找到则输出其下标(从 0 开始),否则输出 -1。同时统计比较次数并输出。 **输入格式** 第一行包含一个整数 $ n $($ 1 \leq n \leq 1000 $)。 第二行包含 $ n $ 个升序排列的整数。 第三行包含一个整数 $ x $,表示要查找的目标值。 **输出格式** 第一行输出目标值 $ x $ 的下标(如果不存在则输出 -1)。 第二行输出比较次数。 **样例输入** ``` 5 12 31 55 89 101 31 ``` **样例输出** ``` 1 3 ``` **参考代码** ```c #include <stdio.h> int BinarySearch(int arr[], int n, int x, int *count) { int low = 0, high = n - 1; *count = 0; while (low <= high) { (*count)++; int mid = (low + high) / 2; if (x > arr[mid]) { low = mid + 1; } else if (x < arr[mid]) { high = mid - 1; } else { return mid; } } return -1; } int main() { int n, x, count; scanf("%d", &n); int arr[n]; for (int i = 0; i < n; i++) { scanf("%d", &arr[i]); } scanf("%d", &x); int result = BinarySearch(arr, n, x, &count); printf("%d\n%d\n", result, count); return 0; } ``` --- #### 题目 2:带递归的二分查找填空题 **题目描述** 完成以下递归版本的二分查找函数 `BinarySearch`,并在主程序中调用该函数以测试其正确性。 ```c int BinarySearch(int arr[], int low, int high, int x, int *count) { if (low > high) { return -1; } int mid = (low + high) / 2; (*count)++; if (x == arr[mid]) { return mid; } else if (x > arr[mid]) { return BinarySearch(arr, mid + 1, high, x, count); // 填空处 } else { return BinarySearch(arr, low, mid - 1, x, count); // 填空处 } } ``` **提示** 递归版本的二分查找需要明确递归终止条件,并确保每次递归时调整搜索范围。 --- #### 题目 3二分查找的边界条件处理 **题目描述** 设计一个二分查找函数,能够正确处理以下边界条件: - 目标值小于数组中最小值。 - 目标值大于数组中最大值。 - 数组中存在重复元素。 **输入格式** 第一行包含一个整数 $ n $($ 1 \leq n \leq 1000 $)。 第二行包含 $ n $ 个升序排列的整数。 第三行包含一个整数 $ x $,表示要查找的目标值。 **输出格式** 输出目标值 $ x $ 的第一个出现位置(从 0 开始)。如果不存在,则输出 -1。 **样例输入** ``` 6 1 2 2 3 4 5 2 ``` **样例输出** ``` 1 ``` **参考代码** ```c #include <stdio.h> int BinarySearchFirstOccurrence(int arr[], int n, int x, int *count) { int low = 0, high = n - 1; *count = 0; int result = -1; while (low <= high) { (*count)++; int mid = (low + high) / 2; if (x == arr[mid]) { result = mid; high = mid - 1; // 继续向左查找第一个出现的位置 } else if (x > arr[mid]) { low = mid + 1; } else { high = mid - 1; } } return result; } int main() { int n, x, count; scanf("%d", &n); int arr[n]; for (int i = 0; i < n; i++) { scanf("%d", &arr[i]); } scanf("%d", &x); int result = BinarySearchFirstOccurrence(arr, n, x, &count); printf("%d\n", result); return 0; } ``` --- #### 题目 4:二分查找的时间复杂度析 **题目描述** 假设数组长度为 $ n $,请二分查找算法的时间复杂度,并证明其最坏情况下的时间复杂度为 $ O(\log n) $。 **解答** 二分查找在每次迭代中将搜索范围缩小一半[^1]。假设初始搜索范围为 $ n $,经过 $ k $ 次迭代后,搜索范围变为 $ n / 2^k $。当搜索范围缩小到 1 时,满足以下条件: $$ n / 2^k = 1 \implies k = \log_2 n $$ 因此,二分查找的最坏情况下的时间复杂度为 $ O(\log n) $[^2]。 --- #### 题目 5:二分查找的应用场景 **题目描述** 列举二分查找算法的常见应用场景,并简要说明其适用条件。 **解答** 二分查找适用于以下场景: 1. **有序数组中的查找**:如查找某个特定值或统计某个区间内的元素数量。 2. **寻找最近邻元素**:如查找小于等于目标值的最大元素或大于等于目标值的最小元素。 3. **优化问题**:如通过二法求解最大值最小化或最小值最大化的问题。 适用条件包括:数据必须有序,且支持随机访问(如数组或链表)[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值