控制流图遍历 - BFS,但确保前任访问

时间:2015-06-08 11:34:55

标签: algorithm graph tree tree-traversal graph-traversal

我遇到的情况是,在访问节点之前必须访问节点的前驱。所以,这是代码:

nodeQ.Enqueue(rootNode);

while(!nodeQ.Empty())
{
    node = nodeQ.Dequeue();
    ForEach(var predecessor in node.Predecessors)
    {
        if(predecessor is not visited)
        {
            //put the node back into the queue
            nodeQ.Enqueue(node);
            skip = true;
            break;
        }
    }
    if(skip)continue;

    Visit(node)

    foreach(var successor in node.Successors)
    {
        if(successor is not already visited)
        {
            nodeQ.Enqueue(successor);
        }
    }   
}

上述算法适用于没有循环的线性控制流程图(读取:循环) 正常的BFS遍历不能确保在节点本身之前访问节点的前驱。

示例CFG: Control Flow Graph. Root: 0

普通BFS遍历将是: 0,1,2,3,12,4,5,9,10,11,8,6,7

但是,我希望订单为0,1,2,3,4,5,6,7,8,9,10,11,12,这可以通过我的代码中的小修改来实现在开头显示。

但是,当涉及到循环时,这种修改将导致无限跳过块。

示例CFG,这可能会失败: Control FLow Graph with Loop

在这种情况下,我的代码将无休止地推迟访问节点1,2,3

所以,我正在寻找一种遍历方式,以确保遍历CFG节点(有或没有循环),以便在节点本身之前访问节点的前驱。

我正在考虑识别后沿,即检查节点N是否是其前任P的支配者,然后P-> N是后备,并且不需要将P视为节点N的前驱。然而,这似乎不起作用,因为节点N并不总是必须支配节点P。

2 个答案:

答案 0 :(得分:2)

我通过首先找到Dominators,创建Dominator Tree然后遍历DFS预订中的树来解决这个问题。

答案 1 :(得分:0)

对于那些寻求CFG和支配者计算指导的人来说,查看IBM WALA tools可能会有用。我在这里找到了很多有用的信息,用于我的特殊任务。