二分查詢又稱折半查詢,優點是比較次數少,查詢速度快,平均效能好;其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序列表。
首先,假設表中元素是按公升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。
總體來說二分查詢是建立在按順序從小到大排好的基礎上的(c++上建議用sort)但是具體問題具體討論;
#include //將**以函式的形式寫在外面很大程度上增加了**的可讀性
int twosearch(int x, int v, int n)
else if(x > v[mid])
else
} return -1;}
int main();
int ans,n;
scanf("%d",&n);
ans = twosearch(n, a, 11);
if(ans==-1)
printf("failure!\n");
else
return 0;
}
//(1)左閉右開:
int binarysearch(seqlist* s, datatype x)
else if (s->array[mid]>x)
else
}}/*這裡int left = 0, right = s->size ;
while (left < right) 這倆句可以看出是左閉右開"[ )"的情況,如果 if (s->array[mid]>x)滿足,那麼x在[left,mid)中,right此時應該設定為mid,如果按照上面**中的right = mid - 1; 就有可能丟失mid對應的那個值,也就是array[mid]=x,這個值被忽略了,就有可能一直找不到x了。*/
//(2)左閉右閉:
int binarysearch(seqlist* s, datatype x)
else if (s->array[mid]>x)
else}}
//這個就是對的。
//(3)死迴圈:
int binarysearch(seqlist* s, datatype x)
else if (s->array[mid]>x)
else
}}
左閉右閉如果像上面一樣滿足 if (s->array[mid]>x),那麼x在[left,mid-1]中,right此時應該設定為mid-1,如果這裡mid不減1,就有可能在錯誤的區間死迴圈,一直找不到不能終止程式。
以下為二分的拓展(個人無聊寫的 有的是知乎上看到的)
1.求最小的i,使得a[i] = key,若不存在,則返回-1
int binary_search_1(int a, int n, int key)
if (a[r] == key) return r;
return -1;
}
2.求最大的i,使得a[i] = key,若不存在,則返回-1
int binary_search_2(int a, int n, int key)
if (a[l] == key) return l;
return -1;
}
3.求最小的i,使得a[i] > key,若不存在,則返回-1
int binary_search_3(int a, int n, int key)
if (a[r] > key) return r;
return -1;
}
4.求最大的i,使得a[i] < key,若不存在,則返回-1
int binary_search_4(int a, int n, int key)
if (a[l] < key) return l;
return -1;
}
實際上,對於3、4,也可以先判斷解是否存在,再進行二分查詢。顯然,上面的**還不夠簡潔。下面是我認為最簡潔的**:
//lower_bound(頭指標,尾指標,查詢的元素)返回非單調遞減序列中第乙個**大於或者等於**被查詢元素的元素的位置;
//upper_bound(頭指標,尾指標,查詢的元素)返回非單調遞減序列中第乙個**大於**被查詢元素的元素的位置;
1.int ans = std::lower_bound(a, a + n, key) - a;
ans = (ans == n || a[ans] != key) ? -1 : ans;
2.int ans = std::upper_bound(a, a + n, key) - a;
ans = (ans == 0 || a[ans - 1] != key) ? -1 : ans - 1;
3.int ans = std::upper_bound(a, a + n, key) - a;
ans = (ans == n) ? -1 : ans;
4.int ans = std::lower_bound(a, a + n, key) - a;
ans = (ans == 0) ? -1 : ans - 1;
二分查詢及其變形
一 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。note 給出的所有元素都大於0,若陣列大小為0,請返回0。方法一 o n public int minnumberinrota...
二分查詢及其變種
返回帶查詢元素key的下標。若沒有key元素,則返回 1。注意 1 while迴圈的條件是low high 2 每次迭代hi mid 1 或lo mid 1 二分查詢,找到該值在陣列中的下標,否則為 1 static int binaryserach int array,int key else i...
二分查詢及其變形
最基本的二分查詢模版 在有序陣列a中查詢key,如果找到,返回位置索引,否則,返回 1 int binarysearch int a,int n,int key else if a mid key else return 1 變種1 如果a有多個key元素,返回最大的,否則,返回 1 int bin...