[二分法] 在一个非降序列中,查找与给定值相同的元素下标

本文介绍了如何使用二分法在非降序整数数组中查找特定元素的下标。首先展示了一个基本的Binarysearch函数,接着探讨了LowerBound函数的实现,该函数返回比给定值小的下标最大元素。最后提到了algorithm库中的lower_bound和upper_bound函数,它们分别用于查找大于等于和大于指定值的元素的下标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*

任务一:北大版 在一个非降序列中,查找与给定值相同的元素下标
写一个 Binarysearch在包含size个元素的、从小到大排序的int数组a里查找元素p,
如果找到,返回元素下标,如果找不到,返回-1. 
*/
#include <iostream>
using namespace std;
int Binarysearch(int a[],int size,int p) {
    int L=0;
    int R=size-1;
    while(L<=R) {//如果区间不为空就继续查找 
        int mid=L+(R-L)/2;//取查找区间正中元素的下标 
        //cout<<L<<" "<<mid<<" "<<R<<endl;
        if(p==a[mid]) return mid;
        else if(p>a[mid]) L=mid+1;//设置新的查找区间的左端点 
        else R=mid-1;//设置新的查找区间的右端点
    }
    return -1;
}
int main() {
    int a[20]= {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
    int mid;
    cout<<Binarysearch(a,20,18)<<endl;//第一个参数 指向数组头的指针 第二个参数 数组大小 第三个参数 要查找的值 
    return 0;
}

/*

任务2:北大写一个函数 LowerBound,在包含size个元素的从小到大排序int数组a里查找比给定整数p小的,下标最大元素。找到则返回其下标 找不到返回-1

思考查找比给定整数p大的,下标最小元素,怎么改?

*/

#include <iostream>

using namespace std;

int LowerBound(int a[],int size,int p) {

  

<think>好的,我现在需要帮用户解决在C++98中使用顺序查找二分法查找实现方法的问题。首先,我得确认用户的需求。他们可能正在学习或复习C++的查找算法,特别是针对线性序列,而且需要兼容C++98的代码示例。C++98的标准可能意味着不能使用C++11及之后的特性,比如auto关键字或者更简洁的初始化方式,这点需要注意。 接下来,我需要回忆顺序查找和二分查找的基本原理。顺序查找很简单,就是逐个比较元素,直到找到目标或遍历完整个序列。而二分查找则需要序列是有序的,每次比较中间元素来缩小搜索范围。这两个算法的时间复杂度分别是O(n)和O(log n),这也是它们的优缺点所在。 然后,我得考虑如何在C++98中正确实现这两个算法。对于顺序查找,函数参数可能包括数组、数组长度和目标值,返回下标。这里需要注意数组越界的问题,循环条件应该是从0到length-1。如果找不到,返回-1。 对于二分查找,由于需要有序序列,所以在示例代码中可能需要先对数组进行排序。但用户的问题可能只是查找部分,所以是否需要包含排序步骤呢?或者用户可能已经有有序数组,只是需要查找方法。不过为了示例的完整性,可能还是应该展示一个完整的例子,包括排序,但需要明确说明排序是二分查找的前提。 然后,考虑到C++98的标准,不能使用std::array或者C++11的容器,所以使用原生数组比较合适。函数参数同样需要传递数组指针和长度。二分查找实现需要注意中间值的计算,避免溢出,所以应该用start + (end - start)/2的方式,而不是(start + end)/2。循环条件是start <= end,确保所有元素都被检查到。 然后,测试这两个函数,可能需要一个main函数来展示用法。例如,定义一个数组,测试顺序查找和二分查找的结果。在二分查找前,必须确保数组有序,所以可能需要先调用排序函数。C++98中的排序可以使用std::sort,但需要包含<algorithm>头文件。 现在,检查可能的错误点。比如顺序查找中,循环是否正确遍历所有元素;二分查找中,中间索引的计算是否正确,以及start和end的更新是否正确。另外,函数的返回值是否正确处理了找不到的情况。 接下来,用户可能需要了解两种算法的区别和应用场景,所以在相关问题中,可以提出关于时间复杂度、适用条件、优化方法等问题。这有助于用户深入理解两者的不同。 后,确保代码示例符合C++98标准,没有使用任何新特性。比如,使用iostream的标准输入输出,头文件的包含正确,函数声明和定义符合C++98规范。同时,代码格式要清晰,注释必要的地方,帮助用户理解。 总结一下,我需要分步骤写出两个查找算法的实现,提供完整的代码示例,并解释其原理和注意事项。然后生成相关问题,帮助用户进一步学习。同时,确保所有说明和代码都符合用户的要求和C++98的标准。</think>以下是在C++98中实现顺序查找二分法查找的详细说明示例代码: ### 一、顺序查找实现 原理:逐个遍历元素直到找到目标值 时间复杂度:$O(n)$ ```cpp #include <iostream> // 顺序查找函数 int sequential_search(const int arr[], int length, int target) { for (int i = 0; i < length; ++i) { if (arr[i] == target) { return i; // 找到返回索引 } } return -1; // 未找到 } // 使用示例 int main() { int numbers[] = {3, 1, 4, 1, 5, 9, 2, 6}; int target = 5; int index = sequential_search(numbers, sizeof(numbers)/sizeof(int), target); if (index != -1) { std::cout << "Found at index: " << index << std::endl; } else { std::cout << "Not found" << std::endl; } return 0; } ``` ### 二、二分法查找实现 原理:基于有序序列的分治策略 时间复杂度:$O(\log n)$ ```cpp #include <iostream> #include <algorithm> // 用于排序 // 二分查找函数 int binary_search(const int arr[], int length, int target) { int start = 0; int end = length - 1; while (start <= end) { int mid = start + (end - start) / 2; // 防溢出计算 if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { start = mid + 1; } else { end = mid - 1; } } return -1; } // 使用示例 int main() { int numbers[] = {3, 1, 4, 1, 5, 9, 2, 6}; int length = sizeof(numbers)/sizeof(int); std::sort(numbers, numbers + length); // 先排序 int target = 5; int index = binary_search(numbers, length, target); if (index != -1) { std::cout << "Found at index: " << index << std::endl; } else { std::cout << "Not found" << std::endl; } return 0; } ``` ### 三、关键差异对比 | 特性 | 顺序查找 | 二分法查找 | |--------------|-------------------|-------------------| | 前提条件 | 无需排序 | 必须有序[^2] | | 时间复杂度 | $O(n)$ | $O(\log n)$ | | 适用场景 | 小型/无序数据集 | 大型有序数据集 | | 实现复杂度 | 简单 | 需要处理边界条件 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值