二分算法--的几点思考
2013-03-25 23:37
260 查看
之前写的二分算法的模板 现在略作更新
点击打开链接
标准的二分算法的形式是:
template<class Typep>
int BinarySearch(Type a[],const Type& x,int n) // 总共n个值 数组从0开始
{
int left=0;
int right=n-1;
while(left<=right){
int middle=(left+right)/2;
if(a[middle]==x)return middle; //返回查找到的位置
if(a[middle]>x)right=middle-1;
else left=middle+1;
}
return -1; //没有找到
}
但是往往题中给出的不是数组中的数,需要在数组中找到比查找的值刚刚大的数,那么我们就需要改动return -1;的值 那么改到什么最好呢?
下面我们就来证明
a[1] a[2] a[3]
10 20 30
a[1]=10; a[2]=20; a[3]=30;
现在我们要查找15;
(1)查找的范围值[1,2] ------这里指的是数组的位置
left=1,right=2;
进入while 循环中
middle=1;
num>a[middle]=a[1];
left=middle+1;
result: left=2; midddle=1,right=1;
跳出循环
(2) 查找的范围是[1,3]
left=1,right=3;
进入while循环
middle=2;
num<a[middle]=a[2]
right=middle-1=1;
middle=2,left=1;
进行第二次循环
middle=1;
a[middle]<num
left=middle+1=2;
left=2; middle=1,right=1;
因为是二分查找的情况 所有的情况都会演变成[1,2]和[1,,3]的情况
然后如果要找刚刚大于一点的 选择left的
若是要找刚刚小于一点的 选择right
---- 上面的这两句话就是更改最后一个return 的值 是他返回left和right
然后要注意的是 可以再所给集合中多添加两个边界值 使之 将所有的范围固定 这样就可以求解了
举个例子
要对下面的8个数进行2分查找
2,55,6,7,35,34,88,56
我们加上两个边界值 -1000和1000 控制范围
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[10]={-1000,1000,2,55,6,7,35,34,88,56};
int BinarySearch(int n,int num){
int left=0;
int right=n-1;
int middle;
while(left<=right){
//printf("left=%d right=%d\n",left,right);
middle=(left+right)/2;
if(a[middle]==num)return middle;
if(a[middle]>num)right=middle-1;
else left=middle+1;
}
return left; //刚刚大于一点的
}
int main()
{
sort(a,a+10);
int n=10; //8个查找数加上两个范围
int num;
for(int i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
while(scanf("%d",&num)!=EOF){
int pos=BinarySearch(n,num);
printf("pos=%d a[%d]=%d\n",pos,pos,a[pos]);
}
}
点击打开链接
标准的二分算法的形式是:
template<class Typep>
int BinarySearch(Type a[],const Type& x,int n) // 总共n个值 数组从0开始
{
int left=0;
int right=n-1;
while(left<=right){
int middle=(left+right)/2;
if(a[middle]==x)return middle; //返回查找到的位置
if(a[middle]>x)right=middle-1;
else left=middle+1;
}
return -1; //没有找到
}
但是往往题中给出的不是数组中的数,需要在数组中找到比查找的值刚刚大的数,那么我们就需要改动return -1;的值 那么改到什么最好呢?
下面我们就来证明
a[1] a[2] a[3]
10 20 30
a[1]=10; a[2]=20; a[3]=30;
现在我们要查找15;
(1)查找的范围值[1,2] ------这里指的是数组的位置
left=1,right=2;
进入while 循环中
middle=1;
num>a[middle]=a[1];
left=middle+1;
result: left=2; midddle=1,right=1;
跳出循环
(2) 查找的范围是[1,3]
left=1,right=3;
进入while循环
middle=2;
num<a[middle]=a[2]
right=middle-1=1;
middle=2,left=1;
进行第二次循环
middle=1;
a[middle]<num
left=middle+1=2;
left=2; middle=1,right=1;
因为是二分查找的情况 所有的情况都会演变成[1,2]和[1,,3]的情况
然后如果要找刚刚大于一点的 选择left的
若是要找刚刚小于一点的 选择right
---- 上面的这两句话就是更改最后一个return 的值 是他返回left和right
然后要注意的是 可以再所给集合中多添加两个边界值 使之 将所有的范围固定 这样就可以求解了
举个例子
要对下面的8个数进行2分查找
2,55,6,7,35,34,88,56
我们加上两个边界值 -1000和1000 控制范围
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[10]={-1000,1000,2,55,6,7,35,34,88,56};
int BinarySearch(int n,int num){
int left=0;
int right=n-1;
int middle;
while(left<=right){
//printf("left=%d right=%d\n",left,right);
middle=(left+right)/2;
if(a[middle]==num)return middle;
if(a[middle]>num)right=middle-1;
else left=middle+1;
}
return left; //刚刚大于一点的
}
int main()
{
sort(a,a+10);
int n=10; //8个查找数加上两个范围
int num;
for(int i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
while(scanf("%d",&num)!=EOF){
int pos=BinarySearch(n,num);
printf("pos=%d a[%d]=%d\n",pos,pos,a[pos]);
}
}
相关文章推荐
- 关于二分算法的一些思考
- 二分算法的一些思考
- 二分查找的几点思考
- [算法]java实现 二分查找 斐波那契数列 静静思考
- 抽签问题的思考(二分算法)
- 火车票订票系统的几点优化思考
- Meanshift算法之再思考
- 转:一位阿里人对数据模型建设的几点思考与总结
- 关于平台的几点思考
- 【转载】年终总结 & 算法数据的思考 & 结尾彩蛋
- 二分匹配,匈牙利算法
- 2011研发管理上的几点思考
- 【计算机算法分析】递归与分治策略——二分搜索与集合划分问题
- 算法-对分查找(二分查找)C++实现
- hdu 2962 Trucking 最短路+二分。。Dijkstra+SPFA两种算法实现。
- C#泛型版的超级优化的快速排序算法和插入排序、二分查找算法
- 查找算法之线性查找和二分查找
- 二分算法(如果要查找的数不存在返回比该值小的最大值)
- UVa11159 - Factors and Multiples(二分匹配匈牙利算法)
- hdu2063 过山车 二分匹配 匈牙利算法