語義規定:在有序向量的區間[lo, hi)內,返回e的秩,若有多個相同值則返回最大的秩,若查詢失敗則返回-1
原理:每次取lo與hi的終點,不停調整區間,經過至多兩次比較可以完成一次迭代。
直到最後lo>=hi時(其實就是lo=hi),此時的區間寬度為0,表示查詢失敗了。
// 二分查詢演算法(版本a):在有序向量的區間[lo, hi)內查詢元素e,0 <= lo <= hi <= _size
template static rank binsearch ( t* s, t const& e, rank lo, rank hi ) //成功查詢可以提前終止
return -1; //查詢失敗
} //有多個命中元素時,不能保證返回秩最大者;查詢失敗時,簡單地返回-1,而不能指示失敗的位置
查詢長度分析:
為了評定各個查詢的細微差距,我們考察查詢長度,同樣有最好最壞和平均。
這裡我們依舊考察平均查詢長度:\(c_(k)\)
設在長度為\(n=2^k-1\)的有序向量中進行查詢
1、成功查詢長度
遞推基:
\(c_(k)=c(1)=2\)
遞推分析:對於成功查詢,總共有三種情況
1.經過1次比較,問題轉化為2^-1的新問題;
2.經過2次比較,問題轉化為2^-1的新問題;
3.經過2次比較,在mid處命中,查詢成功.
那麼則有遞推公式
\[c(k) = [c(k-1)+(2^-1)] + 2 +[c(k-1)+2*(2^-1)]=2*c(k-1)+3*2^-1\]令
\[f(k)=c(k)-3k*2^-1
\]則有
\[f(1)=2;f(k)=2f(k-1)=2^2f(k-2)=\dots=2^f(1)=-2^k
\]於是
\[c(k) = f(k)+3k*2^+1=(\frack-1)*(2^k-1)+ \frack
\]進而得到
\[c_=\frac=\frack-1+\frack*\frac=\frack-1+o(\varepsilon)
\]n趨於無窮時忽略末尾收斂的無窮小量平均查詢長度為:
\[o(1.5k)=o(1.5\cdot log_n)
\]
// 二分查詢演算法(版本b):在有序向量的區間[lo, hi)內查詢元素e,0 <= lo < hi <= _size
template static rank binsearch ( t* s, t const& e, rank lo, rank hi ) //出口時hi = lo + 1,查詢區間僅含乙個元素a[lo]
return e < s[lo] ? lo - 1 : lo; //返回位置,總是不超過e的最大者
} //有多個命中元素時,返回秩最大者;查詢失敗時,簡單地返回-1,而不能指示失敗的位置
template static rank binsearch ( t* s, t const& e, rank lo, rank hi ) //成功查詢不能提前終止
return lo - 1; //迴圈結束時,lo為大於e的元素的最小秩,故lo - 1即不大於e的元素的最大秩
} //有多個命中元素時,返回秩最大者;查詢失敗時,能夠返回失敗的位置
資料結構 有序表查詢
對於已經排好序的表,有 在有序表中,取中間的記錄進行比較,如果相同,匹配成功。如果比中間值小,就在中間記錄的左半區進行查詢,如果大,就在右半區。public static intbinarysearch int key return 1 插值查詢是對折半查詢的改進。折半時 mid l ow h ei...
資料結構與演算法(二)向量結構
陣列 起始於位址a 物理位置連續的一段儲存空間。a a i a i x s.int p a 3,則可以認為p 0 a 3 p 2 就相當於 p p 2 其中 p指向字串 123 的第乙個元素,即 1 指標p向後移兩個元素的位址,即指向 3 而 p 2 才是基於p每次向後移乙個字串的長度,即 p 2 ...
資料結構演算法題 有序矩陣查詢
在乙個二維陣列中,每一行都按照從左到右遞增的順序排序,誒一列都按照從上到下遞增的順序排序,請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否包含了該整數。例如下面的二維陣列就是每行 沒列都遞增排序。如果在這個陣列中查詢數字7,則返回true 找得到 如果查詢數字5,由於陣列不含該數字,...