JavaScript实现深度优先遍历和广度优先遍历

885 阅读2分钟

首先要了解什么事深度优先什么事广度优先。这块涉及到二叉树这方面的只是,学过计算机的肯定都知道二叉树是个什么鬼,这里我再具体介绍下。

树: 是一种非顺序数据结构。对于存储需要快速查找的数据非常有用。

一个树结构包含了一系列存在父子关系的节点,每个节点都有要给父节点(除了顶部的节点:根节点)。

如图所示,这个树,根节点属于第0层,之后按照顺序分层。根节点有俩个子节点,1和2,1有俩个子节点3和4。以此类推,应该很好理解他们的子节点吧。同理父节点就是他们上边的节点,1和2的父节点就是根节点。

树的遍历方式分为中序遍历、先序遍历、后序遍历。

中序遍历

从小到大的顺序访问树的所有节点。 7-3-8-1-4-9-根-5-2-6-10

先序遍历

以优先于后代节点的顺序访问每个节点的。先访问本身,然后是它的左侧节点,最后是右侧节点。 根-1-3-7-8-4-9-2-5-6-10

后序遍历

先访问节点的后代节点,再访问节点本身。 7-8-3-9-4-1-5-10-6-2-根

深度优先(DFS)

方法一:

let deepTraversal = (node, nodeList = []) => {
    if(node !== null) {
        nodeList.push(node)
        let children = node.children
        for(let i = 0; i < children.length; i++) {
            deepTraversal(children[i], nodeList)
        }
    }
    return nodeList;
}

方法二:

let deepTraversal = (node) => {
    let nodes = []
    if(node !== null) {
        nodes.push(node)
        let children = node.children
        for(let i = 0; i < children.length; i++) {
            nodes = nodes.concat(deepTraversal(children[i]))
        }
    }
    return nodes;
}

方法三: 非递归

let deepTraversal = (node) => {
    let stack = []
    let nodes = []
    if(node) {
        stack.push(node)
        while(stack.length) {
            let item = stack.pop()
            let children = item.children;
            nodes.push(item)
            for(let i = children.length - 1; i >= 0; i--) {
                stack.push(children[i])
            }
        }
    }
    return nodes;
}

广度优先(BFS)

let widthTraversal = (node) => {
  let nodes = []
  let stack = []
  if (node) {
    stack.push(node)
    while (stack.length) {
      let item = stack.shift()
      let children = item.children
      nodes.push(item)

      for (let i = 0; i < children.length; i++) {
        stack.push(children[i])
      }
    }
  }
  return nodes
}