最近新学习了很多厉害的数据结构,在大佬们的熏陶之下,也感悟了很多,对大佬们的实力也有了更加深厚的了解(先膜一番orz,换个姿势zto,再来一次owz)
左偏树
左偏树又名可并堆,多被用来对一些需要合并的一个集合体进行操作,但其本身只能用于储存最大值或是最小值,说来还是有一些鸡肋。但是在一些仅仅需要找最大值,并将几个堆合并起来时使用还是会有奇效。就好比猴王(详见我的博客),在这道题中使用可并堆就会有出其不意的效果。
线段树
线段树主要针对的是区间操作,对于大部分区间操作都是非常简单的,所以一般遇到和区间有关的用线段树总没错,其实有的时候代码不如树状数组好写但是还是很好想的,对于找一个连续区间的最大值,还是线段树比较好,毕竟树状数组对一个区间求最大值的操作,要实现的代码量并不比线段少,甚至还要难想和难调。所以具体情况要具体分析。线段树还有一个神奇的应用就是,线段树就可以写扫描线。扫描线的原理也非常简单易懂,就是一根线从下往上一直走,取覆盖的长度可以算出面积和周长,不过代码实现复杂度有点高,编程难度比较大,但还是比较实用,毕竟跑得很快。
树状数组
树状数组最大的功能就是用来求和,用树状数组求和只需要logn的时间,自然是非常的快。其中实现原理中有些二进制的问题还是小有疑惑。为什么要这样操作,只要这样做就行了。二进制真的是一项博大精深的学问,怪不得计算机会使用它作为基础。树状数组用处也不只求和,他还可以用来求第k小,求逆序数对,在求逆序数对方面,树状数组的能力可谓远远超过线段树,线段树简直又难想,有难写。并且树状数组还可以拓展到多维而不是仅仅局限于一维,在多维的求和问题中,树状数组实在优秀至极,令人叹服,代码的实现也颇为简便。实在是不可多得的一种好数据结构。
AVL树
平衡树中的一种,并不是很常用,它是一种基于二叉搜索树而成的一种数据结构。在每次插入时候都对目前子树的根节点进行高度判断,若左右儿子的高度之差大于等于2,就进行一波旋转,旋转分为4种,左旋,左右旋,右旋,右左旋。其中最基础的是单旋,二旋可以通过单旋来实现,因为这里只是小结一番,就不在过多叙述,在接下来的时间里,博主会对这些数据结构一 一( 鬼知道这编译器有什么问题,打不出顿号应该是我输入法的问题-_-||)进行讲解。写AVL树的主要目的和作用是为熟悉旋转操作,方便Splay的书写,要说这玩意儿到底有啥用,确实没啥用,大部分时间我们都更倾向与写Splay毕竟没有那么复杂,效果也非常的好。但技多不压身,多学一门是一门,它也可以锻炼我们的代码能力,何乐而不为呢?
伸展树
Splay也是一种基于二叉搜索树的数据结构,他的主要目的是为了,降低时间复杂度,虽然有时它的时间复杂度很高但平摊下来也只就只是一个log,并不算差,它的旋转分为6类,有单旋,也有双旋,反正你不管怎么旋都要把它旋到根节点。在插入的时候旋一旋,删除的时候旋一旋,把时间复杂度平摊下去,也是十分优秀的一种数据结构。对于这种基础性的数据结构,掌握的最好方法就是记模板,自己写一个模板,然后记住,针对不同的题再在模板的基础添加一些东西即可。