二分搜索法 C++代码实现 恋上数据结构笔记

复习梗概

  1. 二分搜索法的end有两种定义方式,两种分别是什么含义?
  2. 二分搜索法end的两种定义方式分别影响了什么?(结束条件,更新指针)
  3. 二分搜索法的结束条件和更新指针两步代码?
  4. 二分搜索法的整体流程?
  5. 二分搜索法图解
  6. !!!我们不必纠结于二分搜索法mid =(begin+end)/2这个过程,middle是不是真的中间那一位,还是中间两位中的一个(偶数总数),因为是有序数组,严格比较大小缩小搜寻范围即可,mid差一两位没所谓根本
  7. 二分搜索法可以用于优化插入排序

二分搜索法是什么,时间复杂度

二分搜索法 : 用于寻找有序数组中的某个元素的位置 ,平均时间复杂度O(logn)(每次砍一半),没有稳定性


二分搜索法整体流程

  1. 初始化begin和end指针,初始化mid指针
  2. 若mid大于num,更新begin指针,mid小于num更新end指针(假设是递增序列)
  3. 若找到mid=num,退出并返回mid
  4. 若begin与end相遇或错过(视end定义而变),退出并返回没找到
  5. 循环上述

二分搜素法代码(end是数组末元素索引)

//!二分搜索法可以有两种写法,主要区别体现在end的定义,以及找不到元素结束搜索的条件(begin与end的位置关系)上
//! 比如下面这个,end的定义是被搜索那一块数组最后元素的索引
void binarySearch(vector<int> &array, int element)
{
    int begin = 0;//begin代表的是,查找数组中的第一个元素的索引,初始为0
    int end = array.size()-1;//end此时代表的是查找数组的最后一位元素索引
    while (begin <= end)//当begin与end错过时,查找数组中不再有任何元素,搜索结束
    {
        int middle = (begin + end) / 2;
        if (array[middle] == element)
        {
            cout << "Search Success Index = " << middle << endl;
            return;
        }
        else if (element < array[middle])
        {
            end = middle -1;//更新end指针,指向新的搜索数组的末尾元素(不包括middle,所以要-1)
        }
        else if (element > array[middle])
        {
            begin = middle + 1;//更新begin指针,指向新的搜索数组的首元素(不包括middle,所以要+1)
        } 
    }
    cout<<"Element Not Find"<<endl;
    return;
}
输入数组:
1 4 6 8 11 15 29 31
二分搜索基础版
搜索 19
Element Not Find
算法用时:(微秒)
[AlgoTime: 2000 us]
搜索完成

二分搜索法代码(end是数组末元素索引+1)

//! 下面这个,end的定义是被搜索那一块数组最后元素的索引+1
void binarySearch(vector<int> &array, int element)
{
    int begin = 0;//begin代表的是,查找数组中的第一个元素的索引,初始为0
    int end = array.size();
    //!这里需要注意,二分搜索法里的end不是数组最后的索引啦,是查找数组的最后一位的索引+1,初始值等于数组长度,是为了什么?
    while (begin < end)//当begin与end相等时,查找数组中不再有任何元素,搜索结束,画个图就明白了
    {
        int middle = (begin + end) / 2;
        if (array[middle] == element)
        {
            cout << "Search Success Index = " << middle << endl;
            return;
        }
        else if (element < array[middle])
        {
            end = middle;//更新end指针,指向新的搜索数组的末尾元素的后一位(就是middle,所以不用-1)
        }
        else if (element > array[middle])
        {
            begin = middle + 1;
        } 
    }
    cout<<"Element Not Find"<<endl;
    return;
}
输入数组:
1 4 6 8 11 15 29 31
二分搜索基础版
搜索 29
Search Success Index = 6
算法用时:(微秒)
[AlgoTime: 4000 us]
搜索完成

完整代码

#include <iostream>
#include <vector>
#include "MeasureAlgoTime.hpp"
using namespace std;

//二分搜索法 : 用于寻找有序数组中的某个元素的位置 ,平均时间复杂度O(logn)(每次砍一半),没有稳定性

void vectorPrint(vector<int> &array)
{
    for (int i = 0; i < array.size(); i++)
    {
        cout << array[i] << ' ';
    }
    cout << endl;
}

//!二分搜索法可以有两种写法,主要区别体现在end的定义,以及找不到元素结束搜索的条件(begin与end的位置关系)上
//! 比如下面这个,end的定义是被搜索那一块数组最后元素的索引
void binarySearch(vector<int> &array, int element)
{
    int begin = 0;//begin代表的是,查找数组中的第一个元素的索引,初始为0
    int end = array.size()-1;//end此时代表的是查找数组的最后一位元素索引
    while (begin <= end)//当begin与end错过时,查找数组中不再有任何元素,搜索结束
    {
        int middle = (begin + end) / 2;
        if (array[middle] == element)
        {
            cout << "Search Success Index = " << middle << endl;
            return;
        }
        else if (element < array[middle])
        {
            end = middle -1;//更新end指针,指向新的搜索数组的末尾元素(不包括middle,所以要-1)
        }
        else if (element > array[middle])
        {
            begin = middle + 1;//更新begin指针,指向新的搜索数组的首元素(不包括middle,所以要+1)
        } 
    }
    cout<<"Element Not Find"<<endl;
    return;
}

//! 下面这个,end的定义是被搜索那一块数组最后元素的索引+1
void binarySearch1thRE(vector<int> &array, int element)
{
    int begin = 0;//begin代表的是,查找数组中的第一个元素的索引,初始为0
    int end = array.size();
    //!这里需要注意,二分搜索法里的end不是数组最后的索引啦,是查找数组的最后一位的索引+1,初始值等于数组长度,是为了什么?
    while (begin < end)//当begin与end相等时,查找数组中不再有任何元素,搜索结束,画个图就明白了
    {
        int middle = (begin + end) / 2;
        if (array[middle] == element)
        {
            cout << "Search Success Index = " << middle << endl;
            return;
        }
        else if (element < array[middle])
        {
            end = middle;//更新end指针,指向新的搜索数组的末尾元素的后一位(就是middle,所以不用-1)
        }
        else if (element > array[middle])
        {
            begin = middle + 1;
        } 
    }
    cout<<"Element Not Find"<<endl;
    return;
}


int main()
{
    Tools::Time::AlgoTimeUs time1;
    Tools::Time::AlgoTimeUs time2;
    Tools::Time::AlgoTimeUs time3;

    vector<int> array;
    array = {1,4,6,8,11,15,29,31};
    vector<int> array2 = array;
    vector<int> array3 = array;

    cout << "输入数组:" << endl;
    time1.start();
    vectorPrint(array);
    cout << "二分搜索基础版" << endl;
    binarySearch(array,19);
    cout << "算法用时:(微秒)";
    time1.printElapsed();
    cout << "搜索完成"<< endl;

    cout << "输入数组:" << endl;
    time2.start();
    vectorPrint(array2);
    cout << "二分搜索基础版" << endl;
    binarySearch1thRE(array2,29);
    cout << "算法用时:(微秒)";
    time1.printElapsed();
    cout << "搜索完成"<< endl;



    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值