分治法 二分查詢

2021-08-10 08:01:57 字數 1965 閱讀 3840

問題描述:

二分查詢又稱為折半查詢,它要求待查詢的資料元素必須是按關鍵字大小有序排列的。問題描述:給定已排好序的n個元素s1,…,sn,現要在這n個元素中找出一特定元素x。

首先較容易想到使用順序查詢方法,逐個比較s1,…,sn,直至找出元素x或搜尋遍整個序列後確定x不在其中。顯然,該方法沒有很好地利用n個元素已排好序這個條件。因此,在最壞情況下,順序查詢方法需要o(n)次比較。

假定元素序列已經由小到大排好序,將有序序列分成規模大致相等的兩部分,然後取中間元素與特定查詢元素x進行比較,如果x等於中間元素,則演算法終止;如果x小於中間元素,則在序列的左半部繼續查詢,即在序列的左半部重複分解和治理操作;否則,在序列的右半部繼續查詢,即在序列的右半部重複分解和治理操作。可見,二分查詢演算法重複利用了元素間的次序關係。

步驟1:確定合適的資料結構。設定陣列s[n]來存放n個已排好序的元素;變數low和high表示查詢範圍在陣列中的下界和上界;middle表示查詢範圍的中間位置;x為特定元素;

步驟2:初始化。令low=0;high=n-1;

步驟3:middle=(low+high)/2,即指示中間元素;

步驟4:判定low小於等於high是否成立,如果成立,轉步驟5;否則,演算法結束;

步驟5:判斷x與s[middle]的關係。如果x==s[middle],演算法結束;如果x>s[middle],則令low=middle+1;否則令high=middle-1,轉步驟3。

設給定的有序序列中具有n個元素。

顯然,當n=1時,查詢乙個元素需要常量時間,因而t(n)=o(1)。

當n>1時,計算序列的中間位置及進行元素的比較,需要常量時間o(1)。遞迴地求解規模為n/2的子問題,所需時間為t(n/2)。

因此,二分查詢演算法所需的執行時間t(n)的遞迴形式為:

當n>1時,t(n)=t(n/2)+o(1)

=……=t(n/2x)+xo(1)

簡單起見,令n=2x,則x=logn。

由此,t(n)=t(1)+logn=o(1)+o(logn)。因此,二分查詢演算法的時間複雜性為o(logn)。

**實現:

#include using namespace std;

int nbinarysearch(int n,int s,int x);

int binarysearch(int s,int x,int low,int high);

int main()

cout

int m1 = nbinarysearch(n,s,x);

int m2 = binarysearch(s,x,0,n-1);

if(m1>=0)

return -1;

}int binarysearch(int s,int x,int low,int high)

測試:

分治法 二分查詢

1 首先二分查詢滿足分治法的四個條件 1 原問題的解可以通過分解為若干個小的問題來解決 將原陣列序列可分解為兩個子串行 2 小的問題的解決方法和原問題的解決方法大致相似 都是確定乙個序列的上界和下界然後求得mid進行比較 3 小問題的解可以通過合併從而得到原問題的解 在子串行中可以更容易得到解從而r...

分治法 二分查詢

問題 給定已按公升序排好序的n個元素a 0 n 1 現要在這n個元素中找出一特定元素x,返回其 首次 出現的位置。雖說是老問題,但是並不可簡單忽視,網上有人說 十個二分九個錯 還是要好好梳理一下。問題一,區間開閉 設查詢區間左右端點為left與right,這兩個點其實開閉均可,一般統一用閉合。問題二...

分治法 二分查詢

分治 分治法是將乙個規模為n的問題分解為k個規模較小的子問題。注意 這裡的子問題一定是相互獨立且與原問題相同。用遞迴的方法解這些子問題。然後將各子問題的解合併到原問題的解。二分查詢演算法是運用分治的典型例子 分治 二分查詢 給定已按公升序排好序的n個元素a 0 n 1 現要在這n個元素中找出一特定元...