接口与实现
接口与实现
抽象数据类型(ADT,Abstract Data Type )与数据结构(Data Structure)
ADT相当于一种说明书
int n;
float x;
char c;
Vector myVector;
List myList;
向量ADT
从数组到向量
向量ADT接口
接口操作实例
disordered存在多少个紧邻的逆序对是降序的;
当找不到想要找的那个元素时,返回-1,或则返回不超过所要找的那个元素的最大元素的秩;如果重复,则是最后面对应的秩。
用sort对整个向量排序,排成升序。
构造与析构
![](https://i-blog.csdnimg.cn/blog_migrate/c934d931d639133eafe6e4c08c27c196.png)
最后一个是解析:
复制
基于复制的构造
1.首先开辟出足够容量的空间
2.再将区间内的元素逐一复制过来
可扩充向量
静态空间管理
![](https://i-blog.csdnimg.cn/blog_migrate/e9e50d5712f41c437e85d756a4ec0dcb.png)
动态空间管理
![](https://i-blog.csdnimg.cn/blog_migrate/64810ec58eaa63a22135202d8fa576da.png)
扩容算法实现
![](https://i-blog.csdnimg.cn/blog_migrate/d42ed1dae43aacf687a8599de16af3c7.png)
增递式扩容
假如容量每次只加I,则为容量递增策略
加倍式扩容
容量加倍策略
分摊复杂度
![](https://i-blog.csdnimg.cn/blog_migrate/7de4f58eca39b6f596893f2eb8c1dfd3.png)
无序向量
概述
Template<typename T> //Vector{……}
Vector<int 或float或char……> //myVector
Vector<BinTree>//forest;
循秩访问
元素访问
C++中的左值和右值
![](https://i-blog.csdnimg.cn/blog_migrate/4d8d99862a52350b24e9d879fbcc4b9f.png)
插入
右移
区间删除
![](https://i-blog.csdnimg.cn/blog_migrate/2419e682c3b021f15ee5999e232b8b86.png)
为什么_size=lo?
单元素删除
![](https://i-blog.csdnimg.cn/blog_migrate/748aac7dd838c7967fbde50a71ab7858.png)
查找
最终hi可能是查找的那个位置,也有可能是失败的位置。而当hi<lo时,则意味着失败。
唯一话:算法
![](https://i-blog.csdnimg.cn/blog_migrate/915e7c7c69b1e6d798eacd9727762d06.png)
证明它的正确性?
复杂度
遍历
![](https://i-blog.csdnimg.cn/blog_migrate/dc26e22ce23a8fe841da4a71d7157d70.png)
后者的适用性更强
实例:
有序向量:唯一化
有序性
无序:比对(是否相等)
有序:比较(孰大孰小)
有序性及其甄别
唯一化(低效版)
![](https://i-blog.csdnimg.cn/blog_migrate/9ce4875b72dfc36a22384314bd51a791.png)
复杂度(低效版)
![](https://i-blog.csdnimg.cn/blog_migrate/8d714929e8f192552d28c95d03305419.png)
唯一话(高效版)
成批地删除?
从最下方的图来看,duplicates表示与i相同的元素。直接从j跳到i的后一位。
else的话开始下一个while.
实例与分析(高效版)
高效算法:实例与复杂度
共计n-1次迭代,每次常数时间,累计O(n)时间
有序向量:二分查找
概述
之前的无序查找:
Vector::find(e,lo,hi)
有序查找中:
Vector::search(e,lo,hi)
接口
![](https://i-blog.csdnimg.cn/blog_migrate/2200cc240b93739b0a0f376af89e3d7d.png)
从语义上来理解
语义
1+V.search(e)表示e查到的位置再加1,
这样即使失败,我们也需要给出新元素插入的适当的位置。给后继者提供一个参考的依据。
如果查找的值有多个,则返回最后一个再加一的地方插入新的值。还有两种情况,见下图的最后两行。
原理
版本A:
实现
版本A:
建议用小于号
实例
![](https://i-blog.csdnimg.cn/blog_migrate/88319a62555532ccabb2f3fbdd0fe565.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6c7c91404b1eb825a06e5d3f1fe26922.png)
顺序查找的话 复杂度是O(n)
查找长度
版本A:
(a)(b)(c)是成功的情况,一共七种,平均=总次数/7种=29/7=4+
(d)是失败的情况,一共八种,平均=总次数/8种=36/8=4.5=
1
.
5
log
2
8
{\rm{1}}{\rm{.5}}{\log _2}8
1.5log28
有序向量:Fibonacci查找
构思
![](https://i-blog.csdnimg.cn/blog_migrate/8b553182186202d8a84ecd510f6742f7.png)
实现
![](https://i-blog.csdnimg.cn/blog_migrate/906e42b6768b2c0cad5d487b0d338ce8.png)
实例
![](https://i-blog.csdnimg.cn/blog_migrate/639720a35f4f9051898adb8f6c50017f.png)
最优性
![](https://i-blog.csdnimg.cn/blog_migrate/f507d7e9c62c204a118491feed73cc49.png)
有序向量:二分查找(改进)
版本B
实现
![](https://i-blog.csdnimg.cn/blog_migrate/c2cae19d69d8f6b91b31f0b9a1932c44.png)
语义
版本B
版本C
![](https://i-blog.csdnimg.cn/blog_migrate/a073c7b9e8b697faa7e083b4f6c910c3.png)
版本C的正确性
![](https://i-blog.csdnimg.cn/blog_migrate/a0f64a0683e07f454a5efe93da53218a.png)
有序向量:插值查找
Interpolation Search
原理
![](https://i-blog.csdnimg.cn/blog_migrate/6e59ba84ad3eabf6e7c8bee539ab8c02.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1dd35b7cce29832d67a6da615ad123ea.png)
性能
最坏情况:O(hi-lo)=O(n),这和平凡的顺序查找没啥区别。
一般情况:平均而言的查找成本=?
最好情况:稍试即中、初试即中。
![](https://i-blog.csdnimg.cn/blog_migrate/0c32ebadf7fcb1f6f9a047d1288b4fd8.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4a04a5330ad19e688b777cea2279dcc9.png)
字宽折半
![](https://i-blog.csdnimg.cn/blog_migrate/82db0324ce9d05328329255b073afd86.png)
二进制位宽度
综合对比
![](https://i-blog.csdnimg.cn/blog_migrate/6f46ba0160d578558ffd3a4ed4065f9e.png)
大规模:插值查找
中规模:折半查找
小规模:顺序查找