题目:    

        设a[0:n-1]是已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。



回顾:

我们先来用C/C++来实现二分法:

(具体步骤讲解都在代码中的注释,所以我就不多讲了)


先用递归法熟悉一下:

#include<iostream>
using namespace std;
int BinarySearch(int arr[],int L,int R,int p)               //arr数组,size数组长度,需要找的p 
{
	if(L>=R)
	{
		while(L <= R)							//大条件就是L要不大于R 
		{
			int mid = L + (R - L)/2;    			//区间中值 
			if(p == arr[mid])					//判断是否符合 
				return mid+1;					//返回 
			else if(p > arr[mid])				//进一步判断p是满足mid的左边还是右边
					return BinarySearch(arr,mid,R,p);	//设置新的查找区间的左端点
			else
					return BinarySearch(arr,R,mid,p);	//设置新的查找区间的右端点 
		}
	}
	else
		return -1;
}

int main()
{
	int arr[100],n,m;
	puts("请设置你要出入的元素个数:");
	cin>>n;
	puts("请输入你要输入的各个元素:");
	for(int i = 0;i < n;i ++)
		cin>>arr[i];
	puts("请输入你要查找的元素:");
	cin>>m;
	puts("对应位置为:");
	cout<<BinarySearch(arr,0,n,m)<<endl;
	return 0;
}



再用for循环来遍历二分查找:

#include<iostream>
using namespace std;
int BinarySearch(int arr[],int size,int p)	                //arr数组,size数组长度,需要找的p 
{
	int L = 0;						//左区间 
	int R = size - 1;					//右区间 
	while(L <= R)						//大条件就是L要不大于R 
	{
		int mid = L + (R - L)/2;			//区间中值 
		if(p == arr[mid])				//判断是否符合 
			return mid+1;				//返回 
		else if(p > arr[mid])				//进一步判断p是满足mid的左边还是右边
				L = mid + 1;			//设置新的查找区间的左端点
		else
				R = mid - 1;			//设置新的查找区间的右端点 
	}
	return -1;						//未找到 
}

int main()
{
	int arr[100],n,m;
	puts("请设置你要出入的元素个数:");
	cin>>n;
	puts("请输入你要输入的各个元素:");
	for(int i = 0;i < n;i ++)
		cin>>arr[i];
	puts("请输入你要查找的元素:");
	cin>>m;
	puts("对应位置为:");
	cout<<BinarySearch(arr,n,m)<<endl;
	return 0;
}


注意事项:

        二分法道理很简单都是平时写的时候,容易忽略区间边界的问题导致运行出错;

        例如int mid = L + (R - L)/2;我们要注意这些细节性问题;



(懂上面写的二分法之后,再来看下面改进过后用Java来实现的二分搜索算法)

示例代码:

import java.util.Scanner;

class Search{
    public static void main(String[] args)
    {
        int[] arr = {1,2,3,4,5,6,7};
        Scanner in = new Scanner(System.in);
        int s = in.nextInt();
        in.close();
        int mid = BinarySearch(arr,s);
        if(mid >= 0)//判断搜索过后是否返回-1,若是,则结束,若不是,则打印s在数组中的下标位置;
        	System.out.println(s+"所在数组中的下标为:"+mid);
    }
    public static int BinarySearch(int[] arr,int s)
    {
        int L = 0;              //左区间
        int R = arr.length-1;   //右区间
        int mid,i = 0,j = 0;
        while(L  arr[mid])
                    L = mid + 1;
                else
                    R = mid - 1;
        }
        /*当s不在数组中我们可以分成两种情况:1、s大于数组最大值;2、s小于数组最大值;*/
        if(s > arr[arr.length-1])
        	System.out.println("数组中小于"+s+"的最大元素下标:"+i);
        else
        	if(s < arr[arr.length-1])
        		System.out.println("数组中大于"+s+"的最小元素下标:"+j);
        	else
        	{
        		System.out.println("数组中小于"+s+"的最大元素下标:"+i);
        		System.out.println("数组中大于"+s+"的最小元素下标:"+j);
        	}
        return -1;//在数组中未搜索到则返回-1
    }
}

代码仅供参考,看懂思路自己琢磨自己敲,只有在通过练习中领悟和体会其中的抽象,之后遇见什么问题都是迎刃而生的思考;

点赞(0)
 

0.0分

1 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论