个人水平所限,只能谈及几年前的OI省选水平的算法。再高深的,便不清楚了。
声明:算法分类方式与列举顺序借鉴于hzwer同学的《OI省选算法汇总》。
OI算法,大抵可分为以下几类:
- 数据结构
- 字符串相关
- 图论相关
- 数学相关
- 动态规划
- 计算几何
- 搜索相关
- 不保证正确性的算法
- 其他重要工具与方法
下面依次谈一谈。
数据结构
对数据结构的理解,往往随着接触愈发深入。大致会是这样的历程——
- 知道的不多,关注如何实现,实现能力较差
- 会超过十个,关注如何选取,实现愈发纯熟
- 能联系起来,关注如何组合,实现基本无误
- 后面的我也不知道了……
首先必须扫盲一下,按我这种分法,OI的完整数据结构历程怎么也得十步以上。随便一个省队队员,基本都已经超越了我说的这三个阶段。然而,实际工程中,普通工程师们对数据结构的理解却很浅,平衡树都不一定写过,可并堆甚至都没听说过。可这并不说明实际工程不需要对数据结构的理解,只能说明普遍水平低。也正因此,我才能在这里写点东西,糊弄一下不搞OI的人。
我大概到了第三阶段的初期,实现基本无误,开始关注如何组合了。虽然实际工程中依旧会偶尔遇到自己并不了解的数据结构。但这往往并不会阻碍我,毕竟工程中的数据结构并不像OI那么高深,借助自己对数据结构的理解,往往可以很快理解并实现一个从未见过的数据结构。
下面,我将一一介绍我所熟悉的数据结构,供大家参考。
数组、链表
其实,这俩根本不应该算是数据结构,应该算是实现。区分数组与链表,应该算是数据结构的实现入门吧~
- 数组长度固定,链表则更灵活。
- 数组定位访问速度快,链表拼接切分速度快。
堆、并查集、Hash表
- 堆:插入、修改、删除、取最值,时间 O(logN)OlogN 。
- 并查集:合并两个集合、查询两个元素是否在同一集合之中,时间 O(1)O1 。
- Hash表:插入、修改、删除、查询,时间 O(1)O1 。
树状数组、线段树、平衡树、块状数组
- 树状数组:单点修改、区间查询,时间 O(logN)OlogN 。
- 线段树:区间修改、查询,时间 O(logN)OlogN 。
- 平衡树:插入、修改、删除、查询、取第k大值,时间 O(logN)OlogN 。
- AVL、红黑树:经典,很少用。
- Treap:实现快、速度快,好用。
- Splay:还可区间修改、区间查询、区间翻转等等,时间 O(logN)OlogN ,虽然常数大点,但非常灵活,再配上CLJ的实现,简直舒服。
- 块状数组、块状链表:插入、修改、删除、查询、取第k大值,时间 O(N‾‾√)ON 。
可并堆、树套树
- 可并堆:可以合并的堆,依旧保证 O(logN)OlogN 的时间。
- 左偏树:可并堆中的AVL。
- Random Heap:可并堆中的Treap,这是作者的介绍。
- 斜堆:可并堆中的Splay。
- 斐波那契堆:这东西……实现太复杂,换来的也就是理论复杂度低一些,实在没必要-_-#
- 树套树:一棵树的每个结点都是另一种树,以此来结合两种树的优点,同时保证时空复杂度。我比较弱,这个很少写,都忘得差不多了,就不妄言了。
其他数据结构
数据结构还有很多很多种,以后或许还会再多写一点~这里先随便列点吧^_^
- KD树、四分树
- 可持久化数据结构
- 可持久化线段树(主席树)
- 可持久化平衡树
- 可持久化块状数组