递归JSON数据结构的遍历算法

时间:2013-01-30 17:54:20

标签: javascript tree traversal

我正在使用Javascript构建图形编辑器,我需要一种算法来识别两个“节点”对象之间的所有可能路径。

给出以下JSON对象:

{
    "failureNode": {
        "failureNode": {
            "failureNode": {
                "failureNode": {
                    "failureNode": null,
                    "successNode": null,
                    "id": "node-endpointfailure",}
                },
                "successNode": {
                    "failureNode": null,
                    "successNode": null,
                    "id": "node-endpointsuccess",
                },
                "id": "node-1",
            },
            "successNode": {
                "failureNode": null,
                "successNode": null,
                "id": "node-endpointsuccess",
            },
            "id": "node-2",
        },
        "successNode": {
            "failureNode": {
                "failureNode": {
                    "failureNode": null,
                    "successNode": null,
                    "id": "node-endpointfailure",
                },
                "successNode": {
                    "failureNode": null,
                    "successNode": null,
                    "id": "node-endpointsuccess",
                },
                "id": "node-1",
            },
            "successNode": {
                "failureNode": null,
                "successNode": null,
                "id": "node-endpointsuccess",
            },
            "id": "node-3",
        },
        "id": "node-4",
    },
    "successNode": {
        "failureNode": null,
        "successNode": null,
        "id": "node-endpointsuccess",
    },
    "id": "node-root",
}

我需要ID ='node-root'和'node-endpointfailure'的节点之间的所有可能路由。在这个例子中,有两种可能的方法从'Start'开始(在数据结构中是node-root)并结束'Failure'(node-endpointfailure):

  1. 开始 - > node1 - > node2 - > node4 - >失败
  2. 开始 - > node1 - > node3 - > node4 - >失败
  3. 对于此示例,输出将是JSON路径的数组。像这样......

    [
        failureNode.failureNode.failureNode.failureNode,
        failureNode.successNode.failureNode.failureNode
    ]
    

    大多数应用程序都使用jQuery,因此无论是纯Javascript还是jQuery解决方案都可以使用。

2 个答案:

答案 0 :(得分:1)

这应该完成任务:

function recurse(from, to, node) {
    var result = [],
        choices = ["sucessNode", "failureNode"];
    if (!from && to == node.id)
        return [[]];
    if (from == node.id)
        return recurse(null, to, node);
    for (var i=0; i<choices.length; i++) {
        var choice = choices[i];
        if (node[choice] != null) {
            var res = recurse(from, to, node[choice]);
            for (var j=0; j<res.length; j++) {
                res[j].unshift(choice);
                result.push(res[j]);
            }
        }
    }
    return result;
}
recurse('node-root', 'node-endpointfailure', data);

答案 1 :(得分:1)

我发现你选择的表现形式有点奇怪和令人困惑。树不是表示这种情况的最佳方式。你所描述的基本上是一个DAG(有向无环图)。递归表示最终会复制对象。虽然我确信还有其他方法来表示这一点,但简单的表示只是列出每个节点的成功和失败节点,由id标识。停止节点的成功和失败节点将具有空值(或零长度字符串,以较小者为准)。或者你可以有一个单独的字典。

例如,您的图表可以(列表方式)描述为:

[
  {
    id: "Start",
    successNode: "success",
    failureNode: "node-1"
  },
  {
    id: "node-1",
    successNode: "node-3",
    failureNode: "node-2"
  },
  {
    id: "node-2",
    successNode: "success",
    failureNode: "node-4"
  },
  {
    id: "node-3",
    successNode: "success",
    failureNode: "node-4"
  },
  {
    id: "node-4",
    successNode: "success",
    failureNode: "failure"
  },
  {
    id: "success",
    successNode: "",
    failureNode: ""
  },
  {
    id: "failure",
    successNode: "",
    failureNode: ""
  }
]

让您可以轻松编辑图表。只需根据需要添加或删除节点及其值。我可能会使用另一个对象作为字典,以便更快/更容易地找到每个节点。假设我确实有这样的字典dict,那么从一个节点导航到另一个节点并不难看到你最终的位置。