2018-3-31 关于最近某些工作的感想

最近两周的某一项工作就是把 线段树 不断地抽象,然后封装起来,并且逐步引入新的模式来提高效率。
这里稍作总结。


一开始的版本:
https://blog.csdn.net/rsy56640/article/details/79342325
没有泛型,不支持函数设置,只有区间求和查询,还有单点值修改的操作。


稍微调整之后就有了第二个版本:
https://blog.csdn.net/rsy56640/article/details/79344439
https://github.com/rsy56640/rsy_little_lib/tree/master/library_for_algorithm/SegmentTree/SegmentTree_pointer
增加了泛型模板,并且提供了自定义函数,最重要的一点是:
严格地将数据结构剖析清楚:要求运算对类型构成幺半群,
并且增加了一层抽象,这使得整个架构得以确立。


第三个版本就顺理成章了:
https://blog.csdn.net/rsy56640/article/details/79357167
https://github.com/rsy56640/rsy_little_lib/tree/master/library_for_algorithm/SegmentTree/SegmentTree_array
将线段树的结构从指针改为数组,一点区别就在于:
指针实现的线段树版本在整个树结构中间可能会有空隙,于是数组实现版本对此作了一些修改:将长度拓展为2的幂次,多余的部分用幺元来填充。


最后的部分建立在上述的工作之上,并做了大量效率的改进:
https://github.com/rsy56640/rsy_little_lib/tree/master/library_for_algorithm/SegmentTree/SegmentTree_plus
之前的版本都是不支持区间修改的,于是在此引入了lazy模式,将修改值放入对应区间中,并停止向下,直到必要时才执行pushDown(下推)操作向下更新。
这个思想被称为 lazy evaluation ,在工程中被广泛运用,比如COW(写时复制)那样的。
然而在这个版本的开发中遇到了一些问题,因为要支持
1. 基于值的修改
2. 基于增量的累积
鱼唇的我在一开始没有规划好(后面会说到),于是在写完的时候面临一个很诡异的bug:数据量很小时没有问题,但是如果测试数据量很大时,会有2%左右的错误。于是只能硬着头皮去debug。两天之后,无果。
然后重新开始规划,(这里说的规划指的是函数调用前后保持的某些状态的约定或保证,有点类似很多算法中的不变式。有了这种保证,在研究整个程序结构时会得到极大的便利)修改了一些函数的保证,以及对应的操作之后的状态的保证。
这个工作比较麻烦(所以我一开始没做),但是后期的便利程度和维护成本可以极大地提高和下降。

其实这里面还有一点未完成的工作,就是我在考虑是否提供一个接口,
使得用户可以传递一个修改函数。
但是面临一个问题:如果函数不是同态的,就几乎只能去逐个修改。
如果是同态(Homomorphism),像这样 f(x o y)=f(x) o f(y) f ( x   o   y ) = f ( x )   o   f ( y ) ,的确可以做一些优化,
如果有 cache 还好说,但如果有的只是 augment ,还是会面临巨大的麻烦。


先写这么多,以后如果有机会还会写 可持久化线段树(persistent SegmentTree) ,不过那就是另一回事了。


最后,关于这方面的效率只能说差强人意吧,还有很多东西要搞:
RB_Tree, buffer_pool, B+ / LSM,希望这些都可以尽快提上日程(

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值