在嵌套树中定位元素 - JavaScript

Locating element in a nested tree - JavaScript

需要帮助编写一个函数来搜索示例树中的元素。

var sampletree = [
  "a",
  "b",
  "c",
  [
    "d",
    "e",
    [
      "f",
      "h",
      "i",
      [
        "z",
        "x"
      ]
    ]
  ],
  [
    "y",
    "q",
    "t",
    [
      "m",
      "n",
      [
        "o",
        "p"
      ],
      [
        "r",
        "s",
        [
          "u",
          "v"
        ]
      ]
    ]
  ],
  "g"
]

想要 return true/false 通过只使用广度优先搜索 javascript 在树中搜索 o、p、u、v 等内部元素而不使用框架/库.

我使用 for 循环 运行 通过然后 .indexOf 但无法获得它。

你可以使用这个功能:

function findNodeBFS(tree, node) {
    var queue = tree.slice();
    for (var i = 0; i < queue.length; i++) {
        if (queue[i] === node) return true;
        if (Array.isArray(queue[i])) queue = queue.concat(queue[i]);
    }
    return false;
}

var sampletree = [ "a", "b", "c", [ "d", "e", [ "f", "h", "i", [ "z", "x" ] ] ], [ "y", "q", "t", [ "m", "n", [ "o", "p" ], [ "r", "s", [ "u", "v" ] ] ] ], "g" ];

console.log(findNodeBFS(sampletree, "u")); // true
console.log(findNodeBFS(sampletree, "j")); // false

说明

该算法维护一个 queue,您可以将其视为一种 "to do" 列表。它以树的副本开始。代码遍历节点,但仅遍历 top-level 处的节点。每当它遇到一个代表更深层次的数组时,那些 children 被添加到 queue 的末尾,意思是:"I will deal with you later".

这就是这行代码中发生的事情:

if (Array.isArray(queue[i])) queue = queue.concat(queue[i]);

所以如果queue[i]是一个数组,它的元素被附加1(浅拷贝)到队列中。

1 事实上,concat并没有改变给定的数组,而是产生了一个新的数组,它是[=45的串联=]队列和队列[i]。通过将该新数组分配回 queue,我们得到了追加的效果。我们可以这样做 [].push.apply(queue, queue[i]),它通过附加第二个 in-place 来改变第一个。但它可能看起来有点神秘。

请注意,我们没有追加我们找到的 array,而是 in 中的每个元素。所以当循环到达附加数据时,它实际上会访问原始树的更深层次。这确实是 BFS 的意思:首先访问你当前所在层级的节点,当你完成当前层级后才处理更深的层级。队列(先进先出)是执行此操作的理想数据结构。

深度优先搜索变体

DFS 变体将是这个递归 ES6 函数:

function findNodeDFS(tree, node) {
    return Array.isArray(tree) && tree.some( val => findNode(val, node) ) 
           || node === tree;
}