1 介绍
此次project0项目是实现一个键值对存储,数据结构由写时复制的字典树构成。实现的键-值存储可以存储映射到任何类型值的字符串键。键的值存储在表示该键的最后一个字符的节点中(又称终端节点)。例如,考虑在trie中插入kv对("ab", 1)和("ac", "val")。
2 Task1:Copy-On-Write trie
在本任务中,只需要修改
trie .h
和trie .cpp
来实现写时复制(copy-on-write) tree。在写即复制tree中,操作不会直接修改原始tree中的节点。相反,将为修改后的数据创建新节点,并为新修改的trie返回一个新根。写时复制(Copy-on-write)使我们能够在每次操作之后随时以最小的开销访问该树。考虑在上面的例子中插入("ad", 2)
。我们通过重用原始树中的两个子节点来创建一个新的Node2,并创建一个新的值节点2。(见下图)插入
("b", 3)
,我们将创建一个新的根,一个新的节点,并重用以前的节点。通过这种方式,我们可以在每次插入操作之前和之后获得树的内容。只要我们有根对象(Trie类),我们就可以访问当时Trie中的数据。(见下图)插入
(“a”,“abc”)
并删除(“ab”,1)
,我们可以得到下面的trie。注意,父节点可以有值,并且在删除后需要清除所有不必要的节点。
因此,在这里你需要实现三个函数:
Get(key)
:获取键对应的值。Put(key, value)
:设置键对应的值。如果键已经存在,则覆盖现有值。注意,值的类型可能是不可复制的(即std::unique_ptr<int>
)。这个方法返回一个新的树。Delete(key)
:删除键的值。这个方法返回一个新的树。
这些操作都不应该直接在trie本身上执行。您应该创建新的树节点,并尽可能重用现有的树节点。 要创建一个新节点,您应该使用
TrieNode
类上的Clone
函数。要重用新树中的现有节点,可以复制std::shared_pt<TrieNode>
复制共享指针不会复制底层数据。您不应该在此项目中通过使用new
和delete
手动分配内存。当没有人有对底层对象的引用时,std::shared_ptr
将释放对象。
分析:
- 节点类
TrieNode
使用map<char, std::shared_ptr<const TrieNode>>
来存储这种键值结构,,在这里另一个重要的函数是Clone
函数(使用了C++类的构造函数的隐式转换),Clone
函数实现新建树中现有节点 - 叶子类
TrieNodeWithValue
,继承于TrieNode
,增加了叶子节点存值功能 Trie
类,内部声明了root
(初始为NULL),三个上述待实现的功能