之前寫的二分演算法的模板 現在略作更新
點擊開啟連結
標準的二分演算法的形式是:
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]); } }