标签:vector find search binsearch
无序向量区间查找:
template <typename T> //无序向量的顺序查找:返回最后一个元素e的位置;失败时,返回lo - 1
Rank Vector<T>::find(T const & e, Rank lo, Rank hi) const { //assert: 0 <= lo < hi <= _size
while ((lo < hi--) && (e != _elem[hi])); //从后向前,顺序查找
return hi; //若hi < lo,则意味着失败;否则hi即命中元素的秩
}
有序向量区间查找:
// 二分查找算法(版本C):在有序向量的区间[lo, hi)内查找元素e,0 <= lo <= hi <= _size
template <typename T> static Rank binSearch(T* A, T const & e, Rank lo, Rank hi) { /*DSA*/printf("BIN search (C)\n");
while (lo < hi) { //每步迭代仅需做一次比较判断,有两个分支
/*DSA*/ for (int i=0; i<lo; i++) printf(" "); if (lo >= 0) for (int i=lo; i<hi; i++) printf("....^"); printf("\n");
Rank mi = (lo + hi) >> 1; //以中点为轴点
(e < A[mi]) ? hi = mi : lo = mi + 1; //经比较后确定深入[lo, mi)或(mi, hi)
} //成功查找不能提前终止
/*DSA*/ for (int i=0; i<lo-1; i++) printf(" "); if (lo > 0) printf("....|\n"); else printf("<<<<|\n");
return --lo; //循环结束时,lo为大于e的元素的最小秩,故lo - 1即不大于e的元素的最大秩
} //有多个命中元素时,总能保证返回秩最大者;查找失败时,能够返回失败的位置
引入fibnacci数列(所谓的黄金分割):
class Fib { //Fibonacci数列类
private:
int f, g; //f = fib(k - 1), g = fib(k)。均为int型,很快就会数值溢出
public:
Fib(int n) //初始化为不小于n的最小Fibonacci项
{ f = 1; g = 0; while (g < n) next(); } //fib(-1), fib(0),O(log_phi(n))时间
int get() { return g; } //获取当前Fibonacci项,O(1)时间
int next() { g += f; f = g - f; return g; } //转至下一Fibonacci项,O(1)时间
int prev() { f = g - f; g -= f; return g; } //转至上一Fibonacci项,O(1)时间
};
#include "..\fibonacci\Fib.h" //引入Fib数列类
// Fibonacci查找算法(版本B):在有序向量的区间[lo, hi)内查找元素e,0 <= lo <= hi <= _size
template <typename T> static Rank fibSearch(T* A, T const & e, Rank lo, Rank hi) { /*DSA*/printf("FIB search (B)\n");
Fib fib(hi - lo); //用O(log_phi(n = hi - lo)时间创建Fib数列
while (lo < hi) { //每步迭代仅仅做一次比较判断,有两个分支
/*DSA*/ for (int i = 0; i < lo; i++) printf(" "); if (lo >= 0) for (int i = lo; i < hi; i++) printf("....^"); else printf("<<<<|"); printf("\n");
while (hi - lo < fib.get()) fib.prev(); //通过向前顺序查找(分摊O(1))——至多迭代几次?
Rank mi = lo + fib.get() - 1; //确定形如Fib(k) - 1的轴点
(e < A[mi]) ? hi = mi : lo = mi + 1; //比较后确定深入前半段[lo, mi)或后半段(mi, hi)
} //成功查找不能提前终止
/*DSA*/ for (int i = 0; i < lo-1; i++) printf(" "); if (lo > 0) printf("....|\n"); else printf("<<<<|\n");
return --lo; //循环结束时,lo为大于e的元素的最小秩,故lo - 1即不大于e的元素的最大秩
} //有多个命中元素时,总能保证返回最秩最大者;查找失败时,能够返回失败的位置
template <typename T> //在有序向量的区间[lo, hi)内,确定不大于e的最后一个节点的秩
Rank Vector<T>::search(T const & e, Rank lo, Rank hi) const { //assert: 0 <= lo < hi <= _size
return (rand() % 2) ? //按各50%的概率随机使用
binSearch(_elem, e, lo, hi) : fibSearch(_elem, e, lo, hi); //二分查找或Fibonacci查找
}
标签:vector find search binsearch
原文地址:http://blog.csdn.net/ganxiang2011/article/details/45970345