二分查找及模板

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

【算法原理】

    用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。

【分类】

    有序查找(元素必须是有序的,如果是无序的则要先进行排序操作)

【时间复杂度】

    最坏情况下,关键词比较次数为log2(n+1),且期望时间复杂度为O(log2n);

【适用范围】

    如果答案具有特定的范围,并且验证答案是否成立的函数具有单调性。则可以在范围内对答案进行二分验证,从而快速确定答案。

//迭代二分查找模板
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
template<class T>
int GetLen(T& a)//获取数组大小
{
	return sizeof(a)/sizeof(a[0]);
}
int search(int str[],int l,int r,int key)
{
	int low,high,mid;    
	low=l;//尾
	high=r-1;//头 
	while(low<=high)
	{
		mid=(low+high)/2;
		if(str[mid]==key)
		{
			return mid;//查找成功
		}
		if(str[mid]<key)
		{
			low=mid+1;//在后半序列中查找
		}
		if(str[mid]>key)
		{
			high=mid-1;//在前半序列中查找
		}
	}
	return -1;//查找无答案
}
int main()
{
	ios::sync_with_stdio(false);
	int str[11]={1,1,2,3,5,8,13,21,34,55,89};
	int n,addr;
	printf("请输入待查找的关键字:");
	cin>>n;
	addr=search(str,0,GetLen(str),n);
	if(-1!=addr)
	{
		printf("查找成功,关键字%d所在的位置是:%d\n",n,addr+1);
	}
	else
	{
		printf("查找失败!\n");
	}
	return 0;
}
//递归二分查找模板
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
template<class T>
int GetLen(T& a)//获取数组大小
{
	return sizeof(a)/sizeof(a[0]);
}
int search(int str[],int l,int r,int k)
{
	int mid=l+(r-l)/2;
	if(l>r)//如果查找完毕无答案
		return -1;
	else
	{
		if(str[mid]==k)//如果找到答案
			return mid;//返回位置
		if(str[mid]>k)
			return search(str,l,mid-1,k);//找左边
		else
			return search(str,mid+1,r,k);//找右边
	}
}
int main()
{
	ios::sync_with_stdio(false);
	int str[11]={1,1,2,3,5,8,13,21,34,55,89};
	int n,addr;
	printf("请输入待查找的关键字:");
	cin>>n;
	addr=search(str,0,GetLen(str),n);
	if(-1!=addr)
	{
		printf("查找成功,关键字%d所在的位置是:%d\n",n,addr+1);
	}
	else
	{
		printf("查找失败!\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/apro1066/article/details/81185127
今日推荐