二分查詢簡括及其個人看法

2022-05-28 15:33:11 字數 2724 閱讀 6543

二分查詢又稱折半查詢,優點是比較次數少,查詢速度快,平均效能好;其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序列表。

首先,假設表中元素是按公升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。

總體來說二分查詢是建立在按順序從小到大排好的基礎上的(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...