回溯算法

回溯算法处理 5w 条数据优化

❓:我想根据当前节点 id 回溯出他的路径层级扁平数组
💡:

interface TreeNode {
  id: string;
  parentId: string | null;
  name: string;
}

const getNodePath = (tree: TreeNode[], nodeId: string): TreeNode[] => {
  const node = tree.find((item) => item.id === nodeId);
  if (!node) return [];

  if (node.parentId === null) {
    return [node];
  }

  const parentNode = tree.find((item) => item.id === node.parentId);
  if (!parentNode) return [];

  const parentPath = getNodePath(tree, parentNode.id);
  return [...parentPath, node];
};

在上述代码中,getNodePath 函数接收一个树形结构的数组 tree 和当前节点的 IDnodeId 作为参数。首先,通过 tree.find()方法找到当前节点 node。如果节点不存在,则直接返回一个空数组。

接下来,判断当前节点的 parentId 属性。如果为 null,表示当前节点是根节点,直接将其作为路径的起点,返回一个只包含当前节点的数组。

如果 parentId 不为 null,则继续递归调用 getNodePath 函数,传入当前节点的 parentId 作为新的 nodeId。通过递归回溯,我们可以获取到父节点的路径。

最后,将父节点的路径 parentPath 与当前节点 node 合并为一个新的数组,并返回该数组作为当前节点的路径层级扁平数组。

你按照以下方式调用 getNodePath 函数:

const tree: TreeNode[] = [
  { id: "1", parentId: null, name: "Root" },
  { id: "2", parentId: "1", name: "Node 1" },
  { id: "3", parentId: "2", name: "Node 1.1" },
  { id: "4", parentId: "3", name: "Node 1.1.1" },
];

const nodeId = "4";
const nodePath = getNodePath(tree, nodeId);

console.log(nodePath);

输出结果为:

[
  { id: "1", parentId: null, name: "Root" },
  { id: "2", parentId: "1", name: "Node 1" },
  { id: "3", parentId: "2", name: "Node 1.1" },
  { id: "4", parentId: "3", name: "Node 1.1.1" },
];

❓:回溯算法还有优化的空间吗
💡:在上述实现中,回溯算法的时间复杂度为 O(n^2),其中 n 是树的节点数量。这是因为在每个节点的回溯过程中,都需要遍历整个树来查找父节点。

我们可以使用哈希表来优化回溯算法的性能。将树的节点存储在哈希表中,以节点的 ID 作为键,节点本身作为值。这样,在每个节点的回溯过程中,我们可以通过节点的父节点 ID 直接从哈希表中获取父节点,而不需要遍历整个树。

以下是使用哈希表进行优化的示例代码:

interface TreeNode {
  id: string;
  parentId: string | null;
  name: string;
}

const getNodePath = (tree: TreeNode[], nodeId: string): TreeNode[] => {
  const nodeMap = new Map<string, TreeNode>();

  // 构建哈希表
  for (const node of tree) {
    nodeMap.set(node.id, node);
  }

  const node = nodeMap.get(nodeId);
  if (!node) return [];

  if (node.parentId === null) {
    return [node];
  }

  const parentPath = getNodePath(tree, node.parentId);
  return [...parentPath, node];
};

在上述代码中,我们首先创建了一个空的 Map 对象 nodeMap,用于存储树的节点。

接下来,在构建哈希表阶段,我们遍历树的节点,并将节点的 ID 作为键,节点本身作为值,存储在 nodeMap 中。

在回溯阶段我们可以通过节点的 ID 直接从 nodeMap 中获取节点的父节点,而不需要遍历整个树来查找。

使用哈希表进行优化后,回溯算法的时间复杂度为 O(n),其中 n 是树的节点数量。这是因为在回溯过程中,每个节点的父节点都可以在 O(1) 的时间内获取到。

posted @ 2023-11-10 18:51  郭杰前端开发  阅读(14)  评论(0编辑  收藏  举报
## 希望内容对你有帮助,如果有错误请联系我 q: 1911509826,感谢支持