📜  持久数据结构

📅  最后修改于: 2021-04-17 10:07:25             🧑  作者: Mango

到目前为止,这里讨论的所有数据结构都是非持久性的(或外围的)。持久性数据结构是一种数据结构,在被修改时始终保留其自身的先前版本。由于没有就地更新,因此可以将它们视为“不可变的”。

如果可以访问所有版本,但只能修改最新版本,则数据结构将部分保留。如果每个版本都可以访问和修改,则完全持久。融合持久是指我们合并两个或多个版本以获取新版本。这会在版本图上引起DAG。

可以通过简单的复制来实现持久性,但这在CPU和RAM的使用上效率低下,因为大多数操作对DS所做的改动很小。因此,更好的方法是利用新版本和旧版本之间的相似性来共享它们之间的结构。

例子:

  1. 链接列表串联:考虑将两个单链接列表(其中n和m作为节点数)串联在一起的问题。说n> m。我们需要保留版本,即我们应该能够列出原始文件。
    一种方法是制作每个节点的副本并进行连接。 O(n + m)用于遍历列表,O(1)每个用于添加(n + m – 1)个连接。
    另一种方式是更有效的时空方式,它仅遍历两个列表中的一个,并且减少新连接的数量。由于我们假设m 持久性链表

  2. 二进制搜索树插入:考虑在二进制搜索树中插入新节点的问题。作为二叉搜索树,有一个将放置新节点的特定位置。从新节点到BST根的路径中的所有节点都将观察到结构的变化(级联)。例如,新节点为其子节点的节点现在将具有新指针。这种结构上的变化会导致直至根部的完整路径发生变化。考虑下面的树,其中每个节点内列出的节点的值。
    持久树

使数据结构持久化的方法
对于下面建议的方法,版本的更新以及版本的访问时间和空间随我们实现的是完全持久性还是部分持久性而异。

  1. 路径复制:制作我们将要更新的节点的副本。然后继续进行更新。最后,通过数据结构将更改层叠回去,这与我们在上面的第二个示例中所做的非常相似。这将导致一连串的更新,直到到达一个节点为止,没有其他节点指向根。
    如何在时间t访问状态?维护一组由时间戳索引的根。
  2. 胖节点:顾名思义,我们使每个节点都存储其修改历史记录,从而使其“胖”。
  3. 带盒子的节点:可以实现O(1)的时间和空间分摊以进行访问和更新。这种方法是由Sleator,Tarjan及其团队提供的。对于树,它涉及使用可以容纳以下内容的修改框:
    一种。对节点的一种修改(修改可以是对指针之一,对节点的键或对某些其他特定于节点的数据的修改)
    b。应用mod的时间
    时间戳对于达到我们关注的节点版本至关重要。可以在这里进一步了解它。使用这种算法,在任意时间t的情况下,数据结构中最多存在一个带有时间t的修改框。因此,在时间t进行的修改将树分成三部分:
    部分包含时间t之前的数据,一部分包含时间t之后的数据,并且
    一部分不受修改的影响(来源:MIT OCW)。
    非树数据结构可能需要多个修改框,但仅限于节点的度数以分摊O(1)。

有用的链接:

  1. 麻省理工学院开放式课程(Erik Demaine)
  2. 麻省理工学院开放式课程(David Karger)
  3. 丹恩·利弗特(Dann Toliver)的演讲
  4. 维基页面


持久段树|设置1(简介)