【问题标题】:Serializing a Binary Search Tree序列化二叉搜索树
【发布时间】:2012-08-21 02:07:26
【问题描述】:

究竟如何序列化 BST?以最有效的方式做到这一点的正确方法是什么?现在,这太笼统了,所以让我解释一下我的意思。

这是一些伪伪代码:

public int[] serialize(root){
    preorder traversal 
    convert node to binary representation
    add the binary representation to an array
    send array via stream
}

或者

public int serialize(root){
    preorder traversal 
    convert node to binary representation
    send the binary representation via stream
}

我的问题是——创建一个数组并发送它的所有位,这样有效吗?或者我应该跳过整个数组的想法,每次转换一个节点时,将其发送出去以反序列化它?也许这两种实现都是愚蠢的。任何帮助将不胜感激。

【问题讨论】:

  • “最佳”解决方案可能取决于树的表示方式,因此如果不了解这棵树的更多信息,很难说。但如果没有必要(听起来像是),我会跳过数组步骤,然后将这些位序列化。
  • 你是什么意思树是如何表示的?这是一个 BST。左边小,右边大
  • 我的意思是它是如何在内部表示的。您可以将 BST 表示为节点和引用(如链表)或数组,例如(参见 Wikipedia)。
  • 哦,对不起。这更适用于链表版本

标签: java c++ serialization data-structures binary-search-tree


【解决方案1】:

我建议您也看看 google 协议缓冲区 https://developers.google.com/protocol-buffers/docs/overview

【讨论】:

    【解决方案2】:

    这取决于树和数据类型。如果树中节点的顺序很重要,您需要存储足够的信息来重新创建它。如果在数组中,可以使用数组中的位置重新创建结构

    【讨论】:

    • 节点的顺序不是很明显吗?这是一个 BST ..(因为在插入新副本时以预序遍历它会输出一个精确的副本)。但我真正要问的是..我想更多的是关于序列化..如果我发送一个充满位的数组,或者一次发送一个位,这是否重要
    • compareTo 函数可以存在“相等”的元素,并且在重新创建它时,顺序可以不同。但你是对的,功能是一样的
    【解决方案3】:

    BST 只能在后序中序列化,因为前序和中序不是唯一的。

    1) 预购中不唯一

          root                     root
        /     \                   / 
      left    right             left
                                   \
                                   right
    

    2) 按顺序不唯一

         1                 1
        /                   \    
       2                     2
    

    【讨论】:

    • 这两个例子都不正确,因为它们违反了 BST 定义。在第一个示例中,我们假设“right”大于“root”,因此在左子树中不可能有“right”的 BST。在第二个示例中,第一棵树不是有效的 BST,因为 2 不能是 1 的左孩子。
    【解决方案4】:

    如果您所说的“流”是指 C++ iostream,它们已经以合理的大小缓冲,并且插入该缓冲区的成本非常低。标准库成熟;在自己的游戏中击败它非常困难。你需要可利用的细节来获得任何有价值的东西。也就是说:

    您的输出缓冲区应该有多大(退化的情况是单元素缓冲区,即没有缓冲)取决于缓冲区刷新的开销。该开销将具有固定成本和与大小相关的成本——而不是给定缓存效应的简单线性成本。对于更昂贵的固定开销,更大的缓冲区有助于摊销固定费用。例如,如果缓冲区刷新可以触发零拷贝 I/O,那么缓冲所有较大的序列化可能会大大降低成本,但如果输出操作将复制源缓冲区,则缓冲区大小会减少大约四分之一当刷新的固定成本较低时,L1 缓存大小是一个不错的选择。

    这些都不重要,除非序列化所花费的时间将其置于关键路径上,即让它成为用户等待的东西 - 对于这样的事情,除非您谈论数百万个项目,否则很难生产和向上。即便如此,如果您还没有研究过它,几乎可以肯定,您如何生成单个序列化比您选择的缓冲方案中的浪费更多——甚至然后永远不要忘记你是什么赛车。是 I/O 带宽吗?通过低级压缩器发送您的序列化流可以轻松节省更多时间,而不是您可以做的任何事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多