Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Serialization 面试问题-序列化和反序列化n元树_Serialization_Tree_N Ary Tree - Fatal编程技术网

Serialization 面试问题-序列化和反序列化n元树

Serialization 面试问题-序列化和反序列化n元树,serialization,tree,n-ary-tree,Serialization,Tree,N Ary Tree,我最近在面试中遇到了这个问题,面试官要求我创建两个功能。函数1应采用n元树并转换为字节数组,函数2应采用字节[]并构建n元树。若它是一棵二叉树,我会使用null的特殊字符进行预排序遍历,并将其存储在数组中,然后转换为byte[],但这里是n元树(有许多子树)。我不知道如何存储它并用数组重建n元树。有什么想法或公式可以将这个n元树存储到数组中吗?。 非常感谢您的帮助。在我看来,它是递归的一个很好的用途。编写一个方法(子程序、函数),写出一个节点及其下的所有树。它将写出节点,然后写出子节点的数量(叶

我最近在面试中遇到了这个问题,面试官要求我创建两个功能。函数1应采用n元树并转换为字节数组,函数2应采用字节[]并构建n元树。若它是一棵二叉树,我会使用null的特殊字符进行预排序遍历,并将其存储在数组中,然后转换为byte[],但这里是n元树(有许多子树)。我不知道如何存储它并用数组重建n元树。有什么想法或公式可以将这个n元树存储到数组中吗?。
非常感谢您的帮助。

在我看来,它是递归的一个很好的用途。编写一个方法(子程序、函数),写出一个节点及其下的所有树。它将写出节点,然后写出子节点的数量(叶节点为零),然后调用自身来写入每个子节点(如果有的话)。现在在树的顶部节点上调用该方法,您已经序列化了它

要反序列化,请编写在节点中读取的方法。它将读入节点本身,读入子节点的数量,然后读入每个子节点(如果有的话)。在流中调用它一次,它将为您提供顶部节点和所有子节点——整个树


这个故事的寓意是递归(它实际上只是获取和使用堆栈的一种方便方式)对于处理图形非常有用。比你们想象的要多得多的是图表。

事实上,维基百科帮助我找到了解决方案。我能够将n元树存储到数组中,并将其转换为字节[],然后使用以下公式将字节[]转换回数组 在索引k*i+1+c处找到第c个子项
父项位于指数i-1/2

需要区分两种情况:1完全n元树和2稀疏n元树或非完整树。在第一种情况下,假设N=5,那么树中的每个级别i将精确(即不少于,不多于)5^i个节点;另一方面,在第二种情况下,此规则无效,因为树可以通过构造随机填充

完整的n元树可以序列化为一个数组;简单地从完整的二叉搜索树扩展:节点(中间层和叶子)通过级别i相互关联,通过论坛Ni+1+c*实际N相互关联,其中c是第c个子节点。通过采用级别顺序遍历,可以在字节数组中对树进行最佳序列化(不需要更多字符,请稍后阅读)。全面的解释

不幸的是,对于非完全n元树,正如预期的那样,上述公式不适用。因此,需要采取不同的办法。 一种方法是序列化表示没有子指针的特殊字符,或者更好地序列化子指针的空值。这种方法不是最优的,因为还需要更多的字符(总共需要N个额外的字节),但它是一种非常简单可行的方法。让我们看一个例子:

       A
     / | \ 
    B  C  D
   / \     \
  E   F     G
采用预序遍历,将上述非完整n元树序列化如下

 A B E / F / / C / D G / / /
“/”映射空值,并提供将树反序列化为原始树的功能。采用预序遍历访问树并输出上述字符数组。总共有*2*N*个字节被序列化,因为在这种情况下,树值每个正好是1个字符。作为反序列化算法,仍然可以采用预顺序遍历:如上文所示,识别空值映射模式只需很少的修改。C++代码示例是.


总结、序列化和反序列化一个不完整或稀疏的n元树有点棘手,需要更多的字节来强制映射空值。

下面是代码BFS+队列,应该直接读取

class Node:
    def __init__(self, val):
        self.val = val 
        self.children = []

class Codec:
    def serialize(self, root):
        if root is None:
            return ""
        res = [root.val, "#"]
        q = collections.deque([root])
        while q:
            node = q.popleft()
            for child in node.children:
                res.append(child.val)
                q.append(child)
            res.append("#")
        return ",".join(res)

    def deserialize(self, s):
        if len(s) == 0:
            return
        vals = s.split(",")
        q = collections.deque()
        root = Node(vals[0])
        q.append(root)
        i = 1
        while q:
            node = q.popleft()
            i += 1
            while vals[i] != "#":
                child = Node(vals[i])
                node.children.append(child)
                q.append(child)
                i += 1
        return root

n元树是否存储任何数据,还是只需要序列化树的形状?@templatetypedef。它有数据。每个节点可以有o到n个子节点,每个节点将有数据。我们需要以某种方式将其放入数组中,然后从数组中重建它。这是一个已排序的n元树,还是一个未排序的n元树?只有在n元树完成的情况下才是这样。当n元树不完整或不平衡时,该公式无效。需要一种不同的方法:一种简单的方法是存储一个“end”字符来控制递归,这里[1]是一个想法。[1]