Chapter 2 向量

1.1 Fabonacci数:线性递归,返回当前计算值,通过引用记录上一计算值

https://blog.csdn.net/qq_43118572/article/details/120139946

1.2 Vector向量支持的操作接口

https://blog.csdn.net/qq_43118572/article/details/120142465

1.3 删除
  • 区间删除: remove(lo, hi)

    • 这种方式不是删除一次挪动一次数组,大大减少了时间复杂度
template <typename T> int Vector(T)::remove(Rank lo, Rank hi) {if (lo == hi) return 0;// 将hi后继元素搬到lo后面来,再更改_size大小,是减少时间复杂度的精髓while (hi < _size) _elem[lo++] = _elem[hi++];_size = lo;shrink(); // 若有必要,则缩容return hi - lo;
}
  • 单元素删除remove( r ):通过重载remove接口,删除单元素其实是删除区间的特例。
template <typename T> T Vector<T>::remove(Rank r) {T e = _elem[r];remove(r, r+1);return e;
}
1.4 唯一化 【低效版】
  • 算法思想:自前向后考察各元素,若当前元素在前面所有元素出现过,则执行remove操作删除当前元素
template <typename T> int Vector<T>::deduplicate() {int oldsize = _size;Rank i = 1; // 从_elem[1]开始while (i < _size) (find (_elem[i], 0, i) < 0) ? i++ : remove(i);return oldsize - _size;
}
1.5 遍历
  • ( void ( *visit ) ( T& ) ):从中-右-左顺序读——visit是个指针,指向参数为T& 的函数,返回值类型为void。

    // 方法一:
    template <typename T> void Vector<T>::traverse(void (*visit) (T&))  // 借助函数指针机制 {for (int i=0; i < _size; i++)visit(_elemn[i]);
    }// 方法二:
    template <typename T>  // 元素类型
    template <typename VST> // 操作器
    void Vector<T>::traverse(VST& visit) // 借助函数对象机制 {for (int i=0; i < _size; i++)visit(_elemn[i]);  // 遍历变量
    }
    
  • 实例

    template <typename T>
    struct Increase // 函数对象:递增一个T类对象
    {virtual void operator() (T& e)  { e++; }
    }template <typename T>  void increase (Vector<T> &V)
    {V.traverse(Increase<T>());  // 以Increase为基本操作进行遍历
    }
    
1.6 唯一化 【高效版】
  • 前提:在向量已经有序的前提下,去除重复元素

  • 算法思想:有序向量的重复元素必定是一个序列区间,故只需依次保留各区间的起始元素。使用i,j两个变量分别指向相邻子区间的首元素,将后者移至前者的后继位置。

    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;
    }
    
1.7 二分查找
版本A:三支查找法
  • 深入比较[lo, hi) , mi , (mi + 1, hi)
template <typename T> static Rank binSearch(T* A, const & e, Rank lo, Rank hi) {while (lo < hi) {Rank mi = (lo + hi) >> 2;if ( e < A[mi] ) hi = mi;else if ( e > A[mi] ) = lo = mi + 1;elsereturn mi;}return -1;}
  • 这种算法的不足在于:在每一步迭代中为确定左、右分支方向,分别需要做1次或2次元素比较。
  • 解决办法:1)调整前、后区域的宽度,适当地加长(缩短)前后子向量——Fibonacci查找算法 ; 2)两分支法 【 ( e < A[mi] ) ? hi = mi : lo = mi; 】
版本B:两支查找法,错误仅返回-1
  • 深入比较[lo, hi) , [mi , hi)
template <typename T> static Rank binSearch(T* A, const & e, Rank lo, Rank hi) {while ( 1 < hi - lo ) { // 每次迭代只需做一次比较判断,有两个分支;成功查找不能提前终止Rank mi = (hi - lo) >> 1;( e < A[mi] ) ? hi = mi : lo = mi;} // 出口是hi - lo = 1,查找区间仅含一个元素A[lo]return ( e == A[lo] ) ? lo : -1 ;
} // 有多个命中元素时,不能保证返回秩最大者;查找失败时,简单地返回-1, 而不指示失败的位置
  • 成功查找不能提前终止。
  • 最好情况的时间复杂度提高,但最坏情况的时间复杂度下降。
  • 有多个命中元素时,不能保证返回秩最大者
版本C:两支查找法,失败时能返回失败的位置
  • 若在插入新元素e之前通过查找确定适当的插入位置,则希望在查找失败时返回不大(小)于e的最后(前)一个元素,以便将e作为其后继(前驱)插入向量。

  • 深入比较[lo, hi) , (mi, hi)

    template <typename T> static Rank binSearch (T* A, T const& e, Rank lo, Rank hi) {while (lo < hi) {Rank mi = ( hi - lo ) >> 2;( e < A[mi] ) ? hi = mi: lo = mi + 1;} // 查找成功不能提前终止return --lo; // 循环终止时,lo为大于e的元素的最小秩,故lo - 1即不大于e的元素的最大秩
    } // 有多个命中元素时,总能保证返回秩最大者;查找失败时,能够返回失败的位置。
    
  • 循环终止时,lo为大于e的元素的最小秩,故lo - 1即不大于e的元素的最大秩;【原因:我们始终让[0, lo) 的元素小于等于e】

    if (e >= A[mi]) lo = mi + 1;
    
  • 有多个命中元素时,总能保证返回秩最大者;查找失败时,能够返回失败的位置。

1.8 排序器
  • 算法的稳定性:重复元素之间的相对次序在排序前后保持一致。

    • 起泡算法中元素相对位置有所调整的唯一可能是,某元素_elem[i-1] 严格大于 _elem[i],因此该算法是稳定算法

【数据结构C++邓俊辉】Chapter 2 向量相关推荐

  1. 算法与数据结构(邓俊辉)第一章

    算法与数据结构(邓俊辉)第一章 斐波那契数列 斐波那契数列几种方法快慢的对比 斐波那契数列 斐波那契数列几种方法快慢的对比 //头文件 #pragma once class Fib { //Fibon ...

  2. 数据结构(邓俊辉):递归和迭代、分而治之和减而治之(2.例子)

    前文介绍了递归和迭代.减而治之和分而治之的概念. 数据结构(邓俊辉):递归和迭代.分而治之和减而治之(1.概念) 接下来举一些例子来解释: 以数组求和为例: 采用减而治之(线性递归)的办法: int ...

  3. 数据结构(邓俊辉C++)1

    数据结构(邓俊辉C++)

  4. 《数据结构》邓俊辉 网课习题详细解析(第五章:二叉树)

    文章目录 (a)树 (b)树的表示 (c)二叉树 (e1)先序遍历 (e2)中序遍历 (e4)层次遍历 (e5)重构 (a)树 1.下列那种数据结构可以高效地兼顾静态操作和动态操作(D) A.arra ...

  5. 学堂在线:数据结构_邓俊辉(2020秋)——C++ 学习笔记

    Table of Contents 第一章 绪论 1.1 计算机与算法 1.2 复杂度度量 1.3 复杂度分析 1.4 递归与优化 习题 第二章 向量 第一章 绪论 1.1 计算机与算法 计算机科学核 ...

  6. 数据结构(邓俊辉):栈与队列

    栈和队列,是链表的一种特殊情况. 栈:先进后出(FILO) 队列:先进先出(FIFO) 栈: 栈的ADT操作接口: 栈的模板类: template <typename T> class S ...

  7. 数据结构(邓俊辉C++)2

  8. 数据结构 笔记--向量 C++ 语言版 邓俊辉老师

    邓俊辉老师的书. 1 有数组为什么还需要向量? 几乎所有程序设计语言中都会有数组,程序设计语言的开发者将数组作为一种内置的数据类型. 数组在刚开始初始化的时候就已经固定了长度,也可以依照下标查找,但还 ...

  9. 邓俊辉《数据结构》-列表学习笔记

    2021.12.9 向量&列表的关系 向量结构中各数据项的物理存放位置与逻辑次序完全对应,可通过秩直接访问对应的元素,即"循秩访问".好像可以通过一个人的家庭住址找到那个人 ...

最新文章

  1. java实现多线程的4种方式
  2. 双绞线传输距离_详细了解弱电工程最常用到的网络传输介质:同轴电缆、双绞线、光纤...
  3. java汉字转化accic_Java自主学习贴
  4. github 参与开源_开源桥吸引了独特的演讲者和参与者
  5. 学硕论文选题计算机,计算机硕士论文题目分享
  6. java8官网下载地址
  7. 服务器总线协议_第一章----I2C总线协议入门
  8. 电子海图数据购买、安装、更新及使用注意事项
  9. 临床试验中的样本量估算---实践篇
  10. ZDM按横断面水位线河道开挖
  11. RabbitMq报错 Execution of Rabbit message listener failed
  12. fir.im 自动打包上传
  13. python中sqrt(4)*sqrt(9)_Python表达式sqrt(4)*sqrt(9)的值为()
  14. 图扑软件携数字孪生产品与解决方案亮相高交会
  15. 如何确定抽样的样本数量
  16. 视频教程-FFmpeg+OpenGL ES+OpenSL ES打造Android视频播放器-Android
  17. 网上看到的Android面试题集合(精)
  18. GMS特征点代码实践
  19. 国外安全网站、社区论坛、博客、公司、在线工具等整合收集
  20. Nginx + Lua + API:实现精准城市级别的访问控制

热门文章

  1. 林晓炜 网站交易系统 c语言,2011级C语言程序设计期末考试安排-发布.doc
  2. Windows 下安装 Memcached
  3. 安卓开发 切换简繁体
  4. Rikka with Cake 【多校9 HDU 6681】【欧拉定理+扫描线】
  5. 2020年创新药行业双抗药物专题研究报告
  6. css样式块元素中文字垂直居中
  7. Anaconda安装Osmnx详细步骤以及问题解决
  8. 熹微~~~基于Vue开发的昏暗风格的响应式网页!
  9. 数据结构——“图”的相关知识总结
  10. linux服务器怎么设置ssr协议参数,SSR协议和混淆插件说明 | 轩钰博客