【二分搜索算法】|二分搜索,竟然有这么快的查询方式?|二分搜索的两种方式

一,搜索,查询的方式

当我们要查询某一个固定的值的时候,我们首先首先想到的是一个基础的朴素遍历思想,就是对全部的内容都进行遍历一整遍的遍历,这种方法无疑是能够完成这种遍历的,但是这种方式的时间复杂度高达O(n),这个时间复杂度对多次查找的操作是相当的不友好的,众所周知,O(n2) 在数据范围比较大的情况下都是会爆时间的,所以我们要思考一种更加简便的方法,来简化一下这个操作。

当这个数据存在一定的顺序关系的时候,我们可以用这个所谓的关系来比较大小,划定他所存在的区间,这样每次我们都能少遍历一半的数据,所以我们叫这个搜索办法为二分查找。本质的意义就是为这个值逐步划定范围,从而确定这个值的解。
在这里插入图片描述

二,二分算法的实现过程

1,二分的思考

二分搜索在向这个目标值缩短区间这是非常明显的,但是如何这个目标是存在好几个相同的数值的一个区间呢,我们二分算法的两种写法就会产生区别,在这里我喜欢用前二分查找后二分查找来叫他们,他们只有在这个目标值存在多个的时候会返回不同的数值,在不存在目标值或者说目标值为一个的时候返回是相同的操作

目标值不为1个的例子
加粗样式
当然二分查找还有比较重要的一点是:二分查找的操作的数值之间是要有顺序关系的,不要仅仅局限于大小关系.

2,代码实现过程

首先我们看一下我们二分算法需要导入的数据,

int bsearch_1(int l ,int r, int x)
//l:最开始的下标  ,r:是最结尾的下标  x :是查找的数值

当完成这步骤的时候我们要进行二分的查找操作

1.前二分搜索
while (i < j)
{
    
    
	int mid = (l + r) >> 1 ;
	//中间值mid 前搜就是最简单的 l + r
	if(q[mid] >= x)	r = mid ;
	else l = mid + 1 ;
	//前搜要控制后面的值为 = 就是 r = mid 
}
2.后二分搜索
while(i < j)
{
    
    
	int mid = l + r + 1 >> 1;
	if(q[mid] <= x )	l = mid ;
	else r = mid - 1 ;
}

完成搜索操作之后,我们要检验一下这个值到底是不是我们要求的这个值

if(q[r] != x)
	return - 1;
//当搜索不到的时候返回 - 1 ;
else 
	return r; //搜索的最后 r == l

3 ,总代码

#include <iostream>

const int N =100010;

int n , m ,q[N] ;

int  bsearch_1(int l ,int r ,int x)
{
    
    
	while (l < r)
	{
    
    
		int mid = r + l >> 1;
		if(q[mid] >= x )	r = mid ;
		else l = mid + 1 ;
	}
	if(q[l] != x )
		return - 1 ;
	else return l;
}

int bsearch_2 (int l ,int r ,int x )
{
    
    
	while (l < r)
	{
    
    
		int mid  = (l + r + 1 ) >> 1 ;
		if(q[mid] <= x)  l = mid ;
		else r = mid - 1; 
	}
	if(q[l] != x )
		return - 1 ;
	else return l ;
}
//两搜索的差别就是一个前查找,另一个为后查找
using namespace std;
int main ()
{
    
    
    cin >> n >> m;
    for(int i = 0 ; i < n ; i ++ )
        cin >> q[i];
    while ( m -- )
    {
    
    
        int n1;
        cin >> n1 ;
        cout << bsearch_1( 0 , n - 1 , n1 )<<" "<<bsearch_2( 0 , n - 1 , n1 )<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wen030803/article/details/131679132