1. 程式人生 > >資料結構--有序向量(2)

資料結構--有序向量(2)

有序向量:查詢演算法

       統一介面:(各按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