实验代码 + 报告资源:
链接: https://pan.baidu.com/s/1CuuB07rRFh7vGQnGpud_vg
提取码: ccuq
【本篇博客旨在帮助更多人少走弯路,欢迎转载。若转载,请转载全面,图片文字格式要到位,只复制文字的那种可读性很差,就不要转了。】
前言
这学期快结束了,算法课程也进入尾声,这学期一共有6个实验+大作业,一共7个实验,当时做的时候苦于没有思路,虽然网上可以搜到往届前辈的报告,因为没有代码可以参考,导致每次实验都比较艰难。因为伪代码往往不会将算法的全部细节描述出来,而且一些实际编程中的细节,伪代码无法描述,所以有了这个总结。
这篇博客分为几个部分:
首先是容器介绍,因为算法都是基于容器的,我们不需要关系容器怎么实现,我们专注于算法的实现,所以不应该在容器上花费时间。搞定算法实验,先搞定容器。
然后是编程技巧,编程技巧中主要以c++为基础,介绍一些算法实验中有用的技巧,这些技巧能够大大优化代码复杂度或时间复杂度,使编程变得轻松。
然后是实验介绍,这部分介绍每个实验的要求,有那些算法能够实现,然后会有传送门,跳转到每一个实验的讲解报告。
最后是总结以及一些感悟。这部分就是谈谈算法实验是如何折磨我的 心得
容器介绍
既然是算法实验,我们精力自然是放在算法上,不应该花费精力在准备算法的容器上,比如邻接表,我见过有老哥自己写一个链表来存数据的,其实完全没有必要自己写,C++ STL提供了相当方便且高效的容器。写下来介绍一些C++ STL的容器,及其常用场合
vector
简介
vector也就是向量,数组,线性表容器,底层实现就是一维数组。最最最常用的容器,没有之一。
特性
- 初始长度为0,通过
push_back()
方法添加元素进容器尾部,pop_back()
删除尾部元素。 - 当底层线性表长度满时会自动拓宽容器,变为原长度的2倍,会有元素的复制,但是这个代价微乎其微。
- 拥有resize方法,可以通过
.resize(长度)
来产生一个特定长度的vector - 构造函数第一个参数为数组长度,第二个参数为默认装载值,可以通过
vector<int> a(123, 456)
来创建一个长度为123,每一个元素都是456的vector - 支持
[]
运算符,可以快速访问下标,但是不设置越界判断,要小心
增删复杂度
一般使用push_back来增加一个尾部元素,复杂度为O(1)
一般使用pop_back来删除一个尾部元素,复杂度为O(1)
其他位置的增删,不推荐,因为会有元素的移动,复杂度为O(n)
应用场合
任何需要线性存储元素的场合,最常用的容器没有之一。
stack / queue / deque
简介
栈/队列/双端队列容器 底层为线性表
特性
栈:后进先出,push加入元素,pop弹出元素,top返回栈顶元素引用但是不弹出。
队列:先进先出,front返回队头元素引用,push添加元素,pop弹出元素
双端队列:pop_back , pop_front 头尾都可以增删
增删复杂度
O(1)
应用场合
stack的应用相对vector来说较少,因为stack是特化了的vector
queue主要应用于bfs广度优先搜索
deque则更加少,在某些需要快速在首尾增删的线性表,比如滑动窗口最大值问题
map/set
简介
关联式容器,底层是红黑树
特性
通过insert方法插入元素,erase方法删除元素。find方法查找元素。
find方法返回元素迭代器,如果 .find() != .end()
则说明找到
set的迭代器存储元素对象,假设有迭代器对象it,那么通过 *it
即可访问元素
map的迭代去存储元素<键,值>
对,假设有迭代器对象it,那么通过 it->first
即可访问键, it->second
即可访问值
map可以通过[]下标运算符直接找到键对应的值,用法:值 = map[键]
查找/增删复杂度
O(log(2, n))
应用场合
set比较少,主要用于快速查找,map也是,主要也是用于快速查找,比如记忆化递归,键表示状态,值表示答案。因为查找有更优秀的哈希容器,接下来会介绍
unordered_map/set
简介
关联式容器,底层是哈希表,通过对元素的哈希,来快速存取元素,前提是元素拥有高效的哈希函数
特性
插入,访问,删除元素方法同 map/set
注:如果使用自定义类型,需要在构造函数传入自定义的哈希函数与比较函数
参考:【C++ 自定义哈希函数使得自制数据类型也可使用STL的哈希set,map】
查找/增删复杂度
O(1)
应用场合
unordered_map用于记忆化递归比较多,尤其是那些【键】不连续的问题,比如消消乐,就不能开mem数组来表示,而是用哈希把他们映射到连续的内存
unordered_set用于存储不重复元素,比如要筛重复元素,或者要快速查找一些元素是否在某个集合中(主要是这个 快速查找),舒适好用~~(就是insert插入元素效率略低 常数代价。。。)~~
priority_queue
简介
优先队列容器,底层是堆,队头总是保存最大(小)值
详情见【C++ STL 优先队列(priority_queue)容器的简单使用】
特性
push插入元素,pop弹出队头元素,top返回队头元素引用
增删复杂度
O(log(2, n))
应用场合
广泛,只要用到堆的地方,都可以用。主要用于在动态更新的序列中快速获取最值的场合。你可以用来堆排,topk,最高标号预流