深度优先搜索:错误的迭代DFS结果顺序

时间:2016-02-07 19:08:16

标签: algorithm actionscript-3 flash math

我正在尝试使用DFS算法对等长矩形进行排序。 递归版本完美无缺 这是我的实施:

            if (node.discovered)
                return;

            node.discovered = true;

            for (var i:int = 0, length:int = node.behindNodes.length; i < length; i++)
            {
                var currentNode:IsoNode = node.behindNodes[i];

                if (!currentNode.discovered)
                {
                    visitNode(currentNode, container);
                }
            }

            container.addChild(node);


然而,到处发布的迭代算法(例如:https://en.wikipedia.org/wiki/Depth-first_search)给了我绝对错误的顺序。

这是我的实施:

    if (node.discovered)
        return;

    var stack:Vector.<IsoNode> = new <IsoNode>[node];

    while (stack.length)
    {
        var currentNode:IsoNode = stack.pop();

        if (currentNode.discovered)
            continue;

        currentNode.discovered = true;

        for (var i:int = 0, length:int = currentNode.behindNodes.length; i < length; i++)
        {
            var behindNode:IsoNode = currentNode.behindNodes[i];

            if (!behindNode.discovered)
            {
                stack.push(behindNode);
            }
        }

        container.addChild(currentNode);
    }
  

似乎它试图将父节点放在第一位而不是放在第一位   链的结尾

为什么这个版本的算法存在?这样的感觉是原始算法的半反转版本。

我该如何解决?如何使其返回与递归版本相同的结果?因为乍一看我需要为这个版本提供完全形成的堆栈(而不是使用算法本身),但它没有任何意义!

排序的想法是以正确的顺序获取等距节点 - 从最远到最近。每个节点都保存有关后面节点的信息。

基本上我们有图表

node_1->()  
node_2->(node_3)  
node_3->(node_1)  

递归版本示例:
正确顺序:node_1 node_3 node_2

recursive http://yiffa.net/i/4tX.png

迭代版本的示例:
不正确顺序:node_1 node_2 node_3

iterative http://yiffa.net/i/4tY.png

1 个答案:

答案 0 :(得分:0)

我想不接受我的回答,因为也许我对那个常见的迭代DFS错了。

我想,我自己想出了如何正确模拟这个算法的堆栈。

这是我的代码:

if (node.discovered)
    return;

var currentNode:IsoNode = node;

currentNode.discovered = true;

var discoveredStack:Vector.<IsoNode> = new <IsoNode>[currentNode];

while (discoveredStack.length)
{
    currentNode = discoveredStack[discoveredStack.length - 1];

    while (currentNode.behindNodes.length)
    {
        var behindNode:IsoNode = currentNode.behindNodes.pop();

        if (!behindNode.discovered)
        {
            behindNode.discovered = true;
            discoveredStack.push(behindNode);
            currentNode = behindNode;
        }
    }

    container.addChild(discoveredStack.pop());
}

无论如何,对我来说,算法是迭代的还是递归的并不重要。如果算法相同且输入相同,则必须返回相同的结果。否则它是一个不同的算法。

如果有人能说出我是对还是错,那就太好了。