2021-11-04

                                       二分查找

简介:        

        二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。二分查找在使用时必须满足必须采用顺序存储结构且必须按关键字大小有序排列。

        在最简单的形式中,二分查找对具有指定左索引和右索引的连续序列进行操作。这就是所谓的查找空间。二分查找维护查找空间的左、右和中间指示符,并比较查找目标或将查找条件应用于集合的中间值;如果条件不满足或值不相等,则清除目标不可能存在的那一半,并在剩下的一半上继续查找,直到成功为止。如果查以空的一半结束,则无法满足条件,并且无法找到目标。

         方法:初始条件:left = 0, right = length-1
                    终止:left > right
                    向左查找:right = mid-1
                    向右查找:left = mid+1

         查找的数据未必是有序的,所以要进行对数据进行排序。但排序会改变数据原有的位置序列。为此我使用了结构体来保存原有的序列。

typedef struct {//typedef 对结构体进行重命名
	int num;    //存放数据
	int index;	//存放数据的原有序列
}Target;//该结构体的别名为Target

对数组进行排序,可以直接调用C++自己库中的排序函数sort,但需要引入头文件<algorithm>.也可以自己写,这里使用的是选择排序。

void Electsort(Target*tar,int l,int r){
	for(int i =0;i<r;i++){
		int index = i;
		for(int j = i+1;j<r+1;j++)
		if(tar[index].num>tar[j].num)
			index =j;
		if(index>i){
			Target temp = tar[index];
			tar[index] = tar[i];
			tar[i] = temp;
		}		
	}	 
}

     在对数组拍完序后,在进行二分查找。若待查找的元素在该数组里,就返回钙元素在元数据的位置序列。反之,不存在就返回-1。

int Serach(Target*tar,int l,int r,int target){
	while(l<=r){
		int mid = (r+l)/2;     
		if(target>tar[mid].num)
			l = mid + 1;
		else if(target<tar[mid].num)
			r = mid - 1;
		else
			return tar[mid].index;  
	}
	return -1;
}
// l,r,mid分别表示为查找数据段的左端,右端,中间。

实例1:
输入:
5
1 2 3 4 5
3
输出:
2
实例2:
输入:
5
1 2 3 4 5
6
输出:
所要查找的元素6不存在

综上,程序的完整代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
typedef struct {
	int num;
	int index;	
}Target;

void Assist(Target*tar,int l,int r,int target);  
void Electsort(Target*tar,int l,int r);
int Serach(Target*tar,int l,int r,int target);

int main(){
	int n;
	printf("元素的个数:"); 
	cin>>n;
    Target tar[n];
    printf("元素:");
	for(int i = 0;i<n;i++){
		cin>>tar[i].num;
		tar[i].index = i;
	}
	while(1){
		int target;
		printf("待查找的值:"); 
		cin>>target;
		Assist(tar,0,n-1,target);
	}
} 

void Assist(Target*tar,int l,int r,int target){
	Electsort(tar,l,r);
	
	int index = Serach(tar,l,r,target);	
	if (index==-1)
		printf("所要查找的元素%d不存在\n",target);
	else
		printf("%d\n",index+1);
}


void Electsort(Target*tar,int l,int r){
	for(int i =0;i<r;i++){
		int index = i;
		for(int j = i+1;j<r+1;j++)
		if(tar[index].num>tar[j].num)
			index =j;
		if(index>i){
			Target temp = tar[index];
			tar[index] = tar[i];
			tar[i] = temp;
		}		
	}	 
}


int Serach(Target*tar,int l,int r,int target){
	while(l<=r){
		int mid = (r+l)/2;
		if(target>tar[mid].num)
			l = mid + 1;
		else if(target<tar[mid].num)
			r = mid - 1;
		else
			return tar[mid].index;  
	}
	return -1;
}

 如果本文有侵犯的您的权益时,请联系作者,对文章进行修改。本人能力有限,不免会出现有错误,所以欢迎各位大佬能够批评指正!万分感谢!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值