資料結構--有序向量(2)
阿新 • • 發佈:2018-12-20
有序向量:查詢演算法
統一介面:(各按50%,要麼是二分查詢,要麼是Fibonacci查詢演算法)
template <tyoename T>//統一查詢演算法,0<=lo<hi<=_size Rank Vector<T>::search(T const & e,Rank lo,Rank hi) const{ return (rand()%2)?//各按50%的概率隨機選用 binSearch(_elem,e,lo,hi)//二分查詢演算法 :fibSearch(_elem,e,lo,hi);//Fibonacci查詢演算法 }
二分查詢:(目標元素 e )
A:對於任一元素x=s[mi],即該有序向量的中間元素的位置,將該向量分為三部分(mi = [lo+hi]/2)
s[lo,mi)<=s[mi]<=s(mi,hi)
將目標元素e和x做比較,情況如下:
(1)e < x :則e若存在,必定在左側區間S[lo,mi),遞迴查詢
(2)x < e :則e若存在,必定在右側區間S(mi,hi),遞迴查詢
(3)e = x:命中,返回。
template <typename T>//在有序向量區間內[lo,hi)內查詢元素e static Rank binSearch(T* A,T const& e, Rank lo, Rank hi ){ while (lo < hi){ Rank mi =( lo+hi )>>1;//以中點為軸點 if (e<A[mi]) hi = mi; else if (A[mi] < e) lo = mi + 1; else return mi;//在mi處命中 } return -1;//查詢失敗 }
效能:比較的次數,即查詢長度,成功失敗的長度大致為O(1.5*logn)
Fibonacci查詢(根據黃金分割來取mi)
向量的長度 n = fib(k) - 1,則可取mi = fib(k - 1) - 1,於是,前、後子向量的長度分別為fib(k-1)-1 、 fib(k-2)-1
template <typename T>//0<=lo<=hi<=_size
static Rank fibSearch(T* A,T const& e,Rank lo,Rank hi){
Fib fib(hi - lo);//用O(log以∮為底n的對數)= O(log以∮為底(hi - lo)的對數)時間建立Fib數列
while (lo < hi){
while (hi - lo < fib.get()) fib.prev();
Rank mi = lo + fib.get() - 1;//按黃金比例切分
if(e < A[mi]) hi = mi;
else if (A[mi]< e) lo = mi +1;
return mi;
}
return -1;
}
查詢長度:∮ = 0.6180339...這時的查詢長度是小於二分查詢的大概是1.44logn