通过与 Jira 对比,让您更全面了解 PingCode

  • 首页
  • 需求与产品管理
  • 项目管理
  • 测试与缺陷管理
  • 知识管理
  • 效能度量
        • 更多产品

          客户为中心的产品管理工具

          专业的软件研发项目管理工具

          简单易用的团队知识库管理

          可量化的研发效能度量工具

          测试用例维护与计划执行

          以团队为中心的协作沟通

          研发工作流自动化工具

          账号认证与安全管理工具

          Why PingCode
          为什么选择 PingCode ?

          6000+企业信赖之选,为研发团队降本增效

        • 行业解决方案
          先进制造(即将上线)
        • 解决方案1
        • 解决方案2
  • Jira替代方案

25人以下免费

目录

有哪些数据结构可以可持久化

可持久化的数据结构:1.可持久化线段树;2.可持久化块状数组;3. 可持久化并查集;4.可持久化字典树;5.可持久化分块。其中,维护历史版本的能力就叫可持久化。

一、可持久化的数据结构

1.可持久化线段树

对于实现可持久化的方法,我们最容易想到的就是开一个 O(N2) 的空间,把所有版本都存储下来。但这样显然会有很多空间是浪费的,因为相较于被修改的部分来说,两个版本之间完全相同的部分显然会更多。与线性结构相比,树型结构更擅长帮助我们分清楚这两个部分,而树形结构中最擅长处理这种修改查询问题的就是线段树。所以我们先介绍一下利用可持久化线段树实现可持久化数组。

2.可持久化块状数组

回忆线段树的修改流程,我们会发现所有的操作都只跟一条链有关 (下放lazytag是个例外,但也跟一条链差不多) ,因此我们在生成新版本的时候,对于未修改的点可以直接使用旧版本的节点,只有发生修改的点才需要新建一个新节点来代替旧节点,这样空间复杂度就可以降到 O(NlogN) ,而修改查询这些都不会收到影响。

3. 可持久化并查集

写作并查集,前置知识却是利用可持久化线段树实现可持久化数组,过分!回顾并查集,其实不过是一个 fa[a] = b,为了可持久化,我们就用可持久化数组来维护 fa[i]。注意这里不能再使用路径压缩了,道理很简单,可持久化要尽可能减少修改的次数。但是我们依然保留了一种优化方式:在维护 fa[i] 的同时维护一个 dep[i] ,表示这个节点的深度,保证在合并时是深度较小的点向深度较大的点合并即可。

4.可持久化字典树

依旧与可持久化线段树的思想类似,这里的可持久化主要体现在插入新串,这个插入过程影响的节点数量也是O(logN)的,因此插入时像线段树一样生成一个新的链即可。

5.可持久化分块

利用和可持久化线段树相似的思想,将每块都编好序号,用一个 O(√n) 的数组来记录一个版本的所有块。当一个块要被修改时,新建一个值为修改后的块的新块,用一个新数组保存新版本所有的块编号即可。

延伸阅读:

二、可持久化数据结构原理

可持久化:将数据结构的所有历史版本记录下来,称为可持久化。

不是所有的数据结构都是可以持久化的,可持久化的数据结构要求其结构稳定,比如堆(是一颗满二叉树,结构稳定)、树状数组、trie(字典树)、线段树等。平衡树就不可以进行持久化操作,因为其存在左旋、右旋的操作。

存下来所有的历史版本有两种方式,一种是每改动一次则全部备份下来;另一种是增量备份。名列前茅种方式时空复杂度都比较高,不使用这种方式,我们这里只讲解增量备份的方式(类似于git)。

增量备份的核心思想是:只记录每个版本与前一个版本不同的部分。

相关文章