【问题标题】:How to serialize a Graph-like AVL tree to disk?如何将类似 Graph 的 AVL 树序列化到磁盘?
【发布时间】:2018-02-03 03:47:06
【问题描述】:

我知道这听起来很奇怪,但就是这样。我有一个数据结构,它基本上是一个修改过的 AVL 树。该结构的每个节点都有一个左孩子和一个右孩子。这些核心指针(左​​和右)将用于将所有数据节点链接在一起并保持数据结构平衡(AVL 旋转)以改进搜索。但这些不是结构中唯一的指针,还有其他指针可以指向树中的任何随机节点(这创建了类似图形的类比)。

树是在运行时通过用户交互 (CLI) 构建的。用户还负责在节点之间创建所有不同的链接。

这种数据结构的一个例子可能是(还没有开始编码,它只是原型):

struct node {
    struct node *left; 
    struct node *right 
    struct node *links[NUM]; // Points to any random node in the tree.
    /* Probably many other fields here that could be either pointers 
       or other data types */
}    

现在,一切都在 RAM 中。一旦用户想要退出,所有的数据节点(整棵树)都应该以二进制模式保存到一个文件中(为了以后重新加载,所以必须考虑到这一点)。

基本上,使用递归树遍历算法来保存 AVL 树很容易(在这种情况下,问题是重复的,因为SO 中已经存在解决方案)。但是,就我而言,我必须保留节点之间任意创建的所有链接。

什么是时间和空间上最有效的方式?

【问题讨论】:

  • 我建议您尝试找到某种可以处理包括指针在内的任意数据的序列化库。尝试自己为这种复杂的数据结构编写序列化通常需要大量工作并且容易出现非常糟糕的错误。
  • @Someprogrammerdude 这是一个很好的提议,从来没想过,哈哈。你知道任何开源 C 库吗?

标签: c algorithm serialization tree


【解决方案1】:

您可以按原样转储您的数据结构(包括指针值),并在每个节点的二进制 blob 中添加其地址。重新加载数据结构时,您将动态分配节点并将它们的新地址存储在哈希表中,其中访问键是旧地址。在最后一遍中,您将按顺序解析哈希表(不使用旧地址作为键),检索每个节点的新地址,并再次使用哈希表作为转换表将其指针字段从旧地址更新为新地址(旧地址作为访问密钥)。

【讨论】:

  • 我已经想过同样的想法,但认为它是一个映射表。哈希表可能非常有效。问题是这种方法在空间上真的很糟糕,因为树可以变得非常非常大,比如 10^7 个节点。在这种情况下,所需的表可能非常大。 8 字节条目将导致在主存储器中维护 80 MB 表。你怎么看?
  • 我认为我们可以实现某种用户空间分页,但是,这看起来确实需要做很多工作。
  • 你有什么样的硬件?如今,最轻的笔记本电脑只有 4GB,80 MB 并不是那么大。如果您真的关心内存占用,您可能应该考虑comingstorm 提出的解决方案。 32 位索引而不是 64 位指针已经在您的数据结构本身上节省了很多。
【解决方案2】:

为每个节点选择一个唯一的索引号,并用它来序列化链接。

这可能需要两次遍历——一次设置索引号,一次进行序列化。在node 中添加一个整数字段来保存索引号;你不应该需要任何其他内存开销。

或者,如果您通过将树节点存储在数组或std::vector 中来管理树节点,那么您已经有了一个方便的索引号,并且您不需要额外的索引字段。此外,您可以将所有链接存储为索引而不是指针,因此您可以按原样序列化您的容器。

【讨论】:

  • 嗯,我已经想到了。这可能是一种将节点保存到磁盘的好方法。这里的问题是重新加载过程,因为我认为您必须进行大量 I/O 才能解决每个链接。你怎么看?
  • 也许我们可以像@Renaud Pacalet 的另一个答案所建议的那样实现某种映射表(哈希表),但是会有一些内存开销。
  • 如果你的链接都是std::vector风格的索引,你不需要将它们转换回指针。如果不是,重新生成链接指针也是一个 2-pass 操作:例如,当反序列化到内存时,将指向新分配节点的指针保存在 std::vector 样式数组中。之后,将每个链接索引转换为指针只是一个数组查找!
猜你喜欢
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
  • 2022-01-10
  • 2016-01-03
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
  • 2011-12-14
相关资源
最近更新 更多