Arrays 如何识别孤立节点

Arrays 如何识别孤立节点,arrays,sorting,multidimensional-array,hierarchical-data,orphaned-objects,Arrays,Sorting,Multidimensional Array,Hierarchical Data,Orphaned Objects,我有一个存储在DB中的节点层次结构。我选择all,将它们存储在一个数组中,然后遍历它们并在内存中创建一个嵌套数组 输入如下所示: [{name:A},{name:B},{name:X,父项:A},{name:Y,父项:A},{name:C}] 输出如下所示: [{name:A,子项:[{name:X},{name:Y}]},{B},{C}] 筑巢的深度没有限制 我遇到的问题是,如果其中一条记录具有无效的父引用,则无法将其放入层次结构中,并且脚本以无限循环结束,试图找到父引用 我打赌有一种方法可以

我有一个存储在DB中的节点层次结构。我选择all,将它们存储在一个数组中,然后遍历它们并在内存中创建一个嵌套数组

输入如下所示:

[{name:A},{name:B},{name:X,父项:A},{name:Y,父项:A},{name:C}]

输出如下所示:

[{name:A,子项:[{name:X},{name:Y}]},{B},{C}]

筑巢的深度没有限制

我遇到的问题是,如果其中一条记录具有无效的父引用,则无法将其放入层次结构中,并且脚本以无限循环结束,试图找到父引用

我打赌有一种方法可以告诉我什么时候掉进了无限循环。对于记录,当在循环中我意识到没有父项可插入时,我将该项推到数组的末尾,因为父项可能存在于该行的下面

我想我应该能够意识到我在一次又一次地循环相同的项目

编辑1-代码 这是重要的一点:

    $cnt = count($array);
    do {
        $item = array_shift($array);
        if ($this->push($item)) {
            $cnt--;
        } else {
            array_push($array, $item);
        }
    } while ($cnt > 0);

($this->push()是一个尝试查找父级的方法,如果成功,将$item插入其层次结构)

看起来您正在使用队列(从前面删除,从后面添加)类型 用于存储未处理节点的数据结构。正如节点一样 插入到输出数据结构中,它们将从队列中删除。如果 无法将节点添加到输出中(因为其“父节点”尚未添加) (已移动到输出数据结构) 它已重新排队。最终,队列应该变为空 除非存在“父节点”不存在的节点(孤立节点)

我想你的算法看起来像

 Do While not QueueEmpty()
    node = Dequeue() ' Remove from the front
    if not AddNodeToTree(node) then Queue(node) 'add to the back
 end
其中,
AddNodeToTree
是成功获取节点的函数 将其添加到输出并返回
True
。否则返回
False
导致节点回收

您应该做的唯一一件事是在队列的后面添加一个sentinal节点 以及一个标志,用于指示至少有一个节点已从队列中使用 在一个完整的循环中。上述算法变为:

set NodeProcessed to False
Queue(SentinalNode) ' marker to identify cycle through queue
Do while not QueueEmpty()
  node = Dequeue()
  if isSentinalNode(node) then
     if NodeProcessed then 
        Queue(node)
        set NodeProcessed to False
     else
        ' Queue contains only orphans or is empty
     end
  end
  if AddNodeToTree(node) then
     set NodeProcessed to True
  else
     Queue(node)
  end
end
SentinalNode
是用于检测循环的标记 通过队列

您的输出数据结构似乎包含一个树的“森林”。就是, 它有几棵不同的树。如果有可能的话 一个给定的节点可以在两个或多个树之间共享,如上所述 算法无法正常工作。如果一个节点最多可能出现在
“森林”中有一棵树,那么上面的应该没问题。

我不明白你怎么能进入无限循环。你能给出脚本代码或者告诉我们脚本算法吗?我在一个do-while循环中处理数组,这样我就可以很容易地在一个无限循环中结束