赞
踩
- 给定已按升序排列的n个元素A[0:n-1],现要在这n个元素中找出某一特定元素(查找关键字:key)
- 二分查找(Binary Search)又称为折半查找,是一种高效的算法。
- 二分查找要求待查找列表中的元素是有序的
设A[low…high]为当前查找区间,首先确定区间的中点位置mid=⌊(low +high)/2⌋;然后将待查的key值与A[mid]进行比较
- (1) 若key=A[mid],则查找成功并返回该元素的下标
- (2) 若key<A[mid],则查找左子表A[low…mid-1]
- (3) 若key>A[mid],则查找右子表A[mid+1…high]
重复上述查找过程,直到找到关键字为key的元素或者查找区间为空为止
总共有n个元素,
渐渐跟下去就是n,n/2,n/4,…n/2^k(接下来操作元素的剩余个数),其中k就是循环的次数
由于你n/2^k取整后>=1
即令n/2^k=1
可得k=log2n,(是以2为底,n的对数)
所以时间复杂度可以表示T(n)=O(log2n)
#include <stdio.h> int binarySearch(int a[], int key, int n) { int low = 0; int high = n - 1; while (high >= low) { int mid = (low + high) / 2; if (key == a[mid]) { return mid; } else if (key > a[mid]) { low= mid + 1; } else { high= mid - 1; } } return -1; } int main() { int numbers[] ={2,4,7,10,11,45,50,59,60,66,69,70,79}; int key = 11; int result = binarySearch(numbers, key,13); printf("%d",result); return 0; }
#include <stdio.h> int binarySearch(int a[], int key, int low, int high) { if (low > high) { return -1; } int mid = (low + high) / 2; if (key == a[mid]) { return mid; } else if(key < a[mid]) { return binarySearch(a, key, low, mid - 1); } else { return binarySearch(a, key, mid + 1, high); } } int binarySearch(int a[], int key, int n) { int low = 0; int high = n - 1; return binarySearch(a, key, low, high); } int main() { int numbers[] ={2,4,7,10,11,45,50,59,60,66,69,70,79}; int key = 11; int result = binarySearch(numbers, key, 13); printf("%d",result); return 0; }
//求凸函数的最大值
while(Right-Left>=1e-6)
{
mid = (Left + Right) / 2
midmid = (mid + Right) / 2;
if(f(mid)>f(midmid))
Right = midmid;
else
Left = mid;
}
题目描述
使用
非递归
/递归
算法,实现二分搜索。
输入
多组数据输入,每组第一个数字为数组的长度n,然后输入n个整数,最后输入待查询的值。
输出
输出待查询值所在的位置,如果没有找到,则返回-1。
样例输入
3 1 2 3 2
4 0 1 3 4 2
样例输出
2
-1
#include <bits/stdc++.h> using namespace std; int a[100]; int main() { int n,m; while(~scanf("%d",&n)) { for(int i=0;i<n;i++) { cin>>a[i]; } scanf("%d",&m); int left=a[0]; int right=a[n-1]; while (left<=right) { int x=(left+right)/2; if(a[x]==m) {printf("%d\n",x+1);break;} else if(a[x]>m) { right=x-1; } else { left=x+1; } } if(left>right) printf("-1\n"); } return 0; }
#include <bits/stdc++.h> using namespace std; int a[100]; int fun(int a[],int left,int right,int m) { if(left<=right) { int x=(left+right)/2; if(a[x]==m) return x; else if(a[x]>m) return fun(a,left,x-1,m); else return fun(a,x+1,right,m); } else return -2; } int main() { int n,m; while(~scanf("%d",&n)) { for(int i=0;i<n;i++) { cin>>a[i]; } scanf("%d",&m); printf("%d\n",fun(a,a[0],a[n-1],m)+1); } return 0; }
题目描述
设a[0:n-1]是已排好序的数组。请改写二分搜索算法,使得当待搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于x的最小元素的位置j;当待搜索元素x在数组中时,返回的i和j相同,均为x在数组中的位置
输入
多组数据输入,每组第一个数字为数组的长度n,然后输入n个整数,最后输入带查询的值x。
输出
输出小于x的最大元素的位置i和大于x的最小元素的位置j;当待搜索元素x在数组中时,返回的i和j相同,均为x在数组中的位置
样例输入
1 2 3 2
4 0 1 3 4 2
样例输出
2 2
2 3
AC代码
#include <bits/stdc++.h> using namespace std; int a[100]; int main() { int n,m; while(~scanf("%d",&n)) { int d=-1; for(int i=1;i<=n;i++) { cin>>a[i]; } scanf("%d",&m); int left=a[1]; int right=a[n]; int i,j; while (left<=right) { int x=(left+right)/2; if(a[x]==m) {d=x;break;} else if(a[x]>m) { right=x-1; } else { left=x+1; } } if(d==-1) { i=right; j=left; } else { i=d; j=d; } printf("%d %d\n",i,j); } return 0; }
如有错误,恳请指正
最后,如果这篇文章对你有帮助,欢迎一键三连
下一篇 分治算法之快速排序。
要么努力,要么放弃
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。