码迷,mamicode.com
首页 > 其他好文 > 详细

Vector::find、search查找

时间:2015-05-25 16:40:15      阅读:495      评论:0      收藏:0      [点我收藏+]

标签: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查找

标签:vector   find   search   binsearch   

原文地址:http://blog.csdn.net/ganxiang2011/article/details/45970345

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!