数据结构(C++)向量 笔记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; //向量规模变化量,即被删除元素总数
}

在这里插入图片描述

二分查找

在这里插入图片描述
在这里插入图片描述

程序实现
// 二分查找算法(版本C):在有序向量的区间[lo, hi)内查找元素e,0 <= lo <= hi <= _size
template <typename T> static Rank binSearch ( T* S, 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 < S[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 - 1; //循环结束时,lo为大于e的元素的最小秩,故lo - 1即不大于e的元素的最大秩
} //有多个命中元素时,总能保证返回秩最大者;查找失败时,能够返回失败的位置

在这里插入图片描述
在这里插入图片描述

Fibonacci查找

Fibonacci查找

黄金分割

在这里插入图片描述
在这里插入图片描述

程序实现
#include "fibonacci/Fib.h" //引入Fib数列类
// Fibonacci查找算法(版本B):在有序向量的区间[lo, hi)内查找元素e,0 <= lo <= hi <= _size
template <typename T> static Rank fibSearch ( T* S, T const& e, Rank lo, Rank hi ) {
   /*DSA*/printf ( "FIB search (B)\n" );
   for( Fib fib ( hi - lo ); lo < hi;  ) { //Fib数列制表备查
      /*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 < S[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的元素的最大秩
} //有多个命中元素时,总能保证返回最秩最大者;查找失败时,能够返回失败的位置
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值