无序向量是指只能够比对而不能够比较的向量,有序向量指不仅具有线性次序,而且在线性次序的基础上还具有元素的大小顺序,有序向量依然不要求元素互异。
1、有序性甄别
template <typename T>
int Vector<T>::disordered()const{
int n = 0;
for(int i = 1; i < _size; i ++)
if(_elem[i-1] > _elem[i]) n ++;
return n;
}
2、唯一化
//低效版
template <typename T>
int Vector<T>::uniquify(){
int oldSize = _size; int i = 1;
while(i < _size)
_elem[i-1] == _elem[i] ? remove(i) : i ++;
return oldSize - _size;
}
//高效版
template <typename T>
int Vector<T>::uniquify(){
Rank i = 0, j = 0;
while(++j < _size)
if(_elem[i] != _elem[j])
_elem[++i] = _elem[j];
_size = ++i; shrink();
return j - i;
}
3、查找
//查找接口,50%概率随机使用二分或者fibnacci查找
template <typename T>
Rank Vector<T>::search(T const& e, Rank lo, Rank hi)const{
return (rand() % 2) ? binSearch(_elem, e, lo, hi) : fibSearch(_elem, e, lo, hi);
}
//二分查找,版本A,有多个元素命中时,不能保证返回秩最大者,查找失败只能简单返回-1
template <typename T>
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;
}
return -1;
}
//Fibonacci查找算法
template <typename T>
static Rank fibSearch(T* A, T const& e, Rank lo, Rank hi){
Fib fib(hi - lo);
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;
else return mi;
}
return -1;
}
//二分查找,版本B,将三分支转化为二分支,无论向哪个分支都只需一次比较,有多个元素命中时,不能保证返回秩最大者,查找失败只能简单返回-1
template <typename T>
static Rank binSearch(T* A, T const& e, Rank lo, Rank hi){
while(1 < hi - lo){
Rank mi = (lo + hi) >> 1;
(e < A[mi]) ? hi=mi : lo=mi;
}
return (e == A[lo]) ? lo:-1;
}
//二分查找,版本C,在区间[lo,hi)内查找不大于e的秩最大者
template <typename T>
static Rank binSearch(T* A, T const& e, Rank lo, Rank hi){
while(lo < hi){
Rank mi = (lo + hi) >> 1;
(e < A[mi]) ? hi=mi : lo=mi+1;
}
return --lo;
}