【问题标题】:How to identify orphaned nodes如何识别孤立节点
【发布时间】:2010-06-04 14:22:29
【问题描述】:

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

输入看起来像这样:

[{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 循环中处理数组,这就是我很容易陷入无限循环的方式

标签: arrays sorting multidimensional-array hierarchical-data orphaned-objects


【解决方案1】:

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

我想你的算法看起来像

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 2017-07-29
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多