繁体   English   中英

如何识别孤立节点

[英]How to identify orphaned nodes

我有一个存储在数据库中的节点层次结构。 我选择所有对象,将它们存储在一个数组中,然后对其进行迭代并在内存中创建一个嵌套的数组。

输入看起来像这样:

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

输出看起来像这样:

[{name:A,children:[{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导致节点回收。

您唯一需要做的就是在队列的后面添加一个标记节点,并添加一个标志,以指示在一个完整的循环中至少有一个节点已从队列中消耗掉。 上面的算法变为:

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是用于检测队列循环的标记。

您的输出数据结构看起来包含一个树木的“森林”。 也就是说,它包含几个不同的树。 如果有可能在两个或更多树之间共享给定节点,则上述算法将无法正常工作。 如果一个节点最多可能出现在“森林”中的一棵树中,则上述方法就可以了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM