STL中的二分查找函数
1、lower_bound函数
在一个非递减序列的前闭后开区间[first,last)中。进行二分查找查找某一元素val。函数lower_bound()返回大于或等于val的第一个元素位置(即满足条件a[i]>=val(first<=i<last)的最小的i的值),当区间的全部元素都小于val时,函数返回的i值为last(注意:此时i的值是越界的!!!!!
)。
比方:已知数组元素是a[10]={0,2,2,2,6,8,10,16,60,100}
当val=0时,函数lower_bound()返回值为0;
当val=1时。函数lower_bound()返回值为1。
当val=2时,函数lower_bound()返回值为1;
当val=3时。函数lower_bound()返回值为4;
当val=4时,函数lower_bound()返回值为4;
当val=5时,函数lower_bound()返回值为4;
当val=6时,函数lower_bound()返回值为4;
当val=7时。函数lower_bound()返回值为5。
当val=8时,函数lower_bound()返回值为5。
当val=9时,函数lower_bound()返回值为6;
当val=10时。函数lower_bound()返回值为6。
当val=11时,函数lower_bound()返回值为7;
当val=59时。函数lower_bound()返回值为8。
当val=60时。函数lower_bound()返回值为8;
当val=61时。函数lower_bound()返回值为9;
当val=100时。函数lower_bound()返回值为9;
当val=101时,函数lower_bound()返回值为10。
当val=150时。函数lower_bound()返回值为10。
当val=500时。函数lower_bound()返回值为10;
STL中函数lower_bound()的代码实现(first是终于要返回的位置)
int lower_bound(int *array, int size, int key) { int first = 0, middle, half, len; len = size; while(len > 0) { half = len >> 1; middle = first + half; if(array[middle] < key) { first = middle +1; len = len - half -1;//在右边子序列中查找 } else len = half;//在左边子序列(包括middle)中查找 } }
vector容器储存序列值时的执行程序:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> #include <limits.h> #define debug "output for debug " #define pi (acos(-1.0)) #define eps (1e-4) #define inf (1<<28) #define sqr(x) (x) * (x) #define mod 1e9+7 using namespace std; typedef long long ll; typedef unsigned long long ULL; int main() { int i,x,n,m; vector<int> a; printf("输入数组长度n(0<n<10000):"); scanf("%d",&n); printf("输入数组的n个元素:"); for(i=0;i<n;i++) { scanf("%d",&x); a.push_back(x); } sort(a.begin(),a.end());//排序(非递减序列) printf("元素值a[i]/下标i: "); for(i=0;i<n;i++) printf("%d/%d ",a[i],i); printf("输入查找的元素m:"); vector<int>::iterator it; while(scanf("%d",&m)!=EOF) { //vector容器储存序列值时的函数调用方式 it=lower_bound(a.begin(),a.end(),m);//返回值是迭代器的值 printf("返回位置对于的值:%d ",*it); printf("输入查找的元素m:"); } return 0; }
数组储存序列值时的执行程序:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> #include <limits.h> #define debug "output for debug " #define pi (acos(-1.0)) #define eps (1e-4) #define inf (1<<28) #define sqr(x) (x) * (x) #define mod 1e9+7 using namespace std; typedef long long ll; typedef unsigned long long ULL; int main() { int i,j,k,n,m,first,last; int a[10000]; printf("输入数组长度n(0<n<10000):"); scanf("%d",&n); printf("输入数组的n个元素:"); for(i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n);//排序(非递减序列) printf("元素值a[i]/下标i: "); for(i=0;i<n;i++) printf("%d/%d ",a[i],i); printf("输入区间[first,last)(first<=last<=n):"); while(scanf("%d%d",&first,&last)!=EOF) { printf("输入查找的元素m:"); scanf("%d",&m); //数组储存序列值时的函数调用方式 j=lower_bound(a+first,a+last,m)-a; printf("返回位置:%d ",j); printf("输入区间[first,last)(first<=last<=n):"); } return 0; }
在一个有序序列(升序或者降序)的区间中。进行二分查找某一元素val。函数upper_bound返回一个迭代器指向该区间中最后一个这个元素的下一个位置(简单的说就是返回可以将元素val插入区间的最后一个位置)。
升序排列的容器:
iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值>key的第一个元素。
降序排列的容器:
iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值<key的第一个元素。
STL中函数upper_bound()的代码实现(first是终于要返回的位置)
int upper_bound(int *array, int size, int key) { int first = 0, len = size-1, half, middle; while(len > 0) { half = len >> 1; middle = first + half; if(array[middle] > key)//中位数大于key,在包括last的左半边序列中查找。len = half; else { first = middle + 1;//中位数小于等于key,在右半边序列中查找。 len = len - half - 1; } } return first; }
数组储存序列值时的执行程序:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> #include <limits.h> #define debug "output for debug " #define pi (acos(-1.0)) #define eps (1e-4) #define inf (1<<28) #define sqr(x) (x) * (x) #define mod 1e9+7 using namespace std; typedef long long ll; typedef unsigned long long ULL; int main() { int i,j,k,n,m; int a[10000]; printf("输入数组长度n(0<n<10000):"); scanf("%d",&n); printf("输入数组的n个元素:"); for(i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n);//排序(非递减序列) printf("元素值a[i]/下标i: "); for(i=0;i<n;i++) printf("%d/%d ",a[i],i); printf("输入查找的元素m:"); while(scanf("%d",&m)!=EOF) { //数组储存序列值时的函数调用方式 j=upper_bound(a,a+n,m)-a; printf("返回位置:%d ",j); printf("输入查找的元素m:"); } return 0; }
3、binary_search函数
函数binary_search是在有序序列的[first,last)中寻找元素value,若存在就返回true,若不存在则返回false。
程序执行例如以下:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> #include <limits.h> #define debug "output for debug " #define pi (acos(-1.0)) #define eps (1e-4) #define inf (1<<28) #define sqr(x) (x) * (x) #define mod 1e9+7 using namespace std; typedef long long ll; typedef unsigned long long ULL; int main() { int i,j,k,n,m; int a[10000]; printf("输入数组长度n(0<n<10000):"); scanf("%d",&n); printf("输入数组的n个元素:"); for(i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n);//排序(非递减序列) printf("元素值a[i]/下标i: "); for(i=0;i<n;i++) printf("%d/%d ",a[i],i); printf("输入查找的元素m:"); while(scanf("%d",&m)!=EOF) { //数组储存序列值时的函数调用方式 j=binary_search(a,a+n,m);//j=upper_bound(a,a+n,m)-a; printf("返回位置:%d ",j); printf("输入查找的元素m:"); } return 0; }