8.BFS和DFS

121 阅读1分钟

1.BFS、DFS

BFS即广度优先搜索,DFS即深度优先搜索,BFS采用队列实现,DFS采用栈实现

2.图结构和二叉树结构

// 图
class Graph{
  constructor(vertices=[]){
    this.vertices = vertices
    this.adjList = new Map()
    this.vertices.forEach(v=>this.adjList.set(v,[]))
  }
  addVertes(v){
    this.vertices.push(v)
    this.adjList.set(v,[])
  }
  addEdge(v,w){
    this.adjList.get(v).push(w)
    this.adjList.get(w).push(v)
  }
}

let graph = new Graph([1,2,3,4,5])
graph.addEdge(1,2)
graph.addEdge(1,3)
graph.addEdge(2,4)
graph.addEdge(2,5)
// 二叉树
let tree = {
  key:5,
  left:{
    key:3,
    left:{
      key:1
    },
    right:{
      key:4
    }
  },
  right:{
    key:6
  }
}

3.BFS遍历图和二叉树

function BFS(graph,cb){ 
  const readList = [] // 已读队列 
  const adjList = graph.adjList 
  let pending = [ graph.vertices[0] ] // 待读队列 
  while (pending.length) { 
    let key = pending.shift() 
    readList.push(key) 
    cb&&cb(key) 
    adjList.get(key).forEach(v=>{ 
      if(!readList.includes(v)&&!pending.includes(v)){ // 互斥,保证只读一遍 
      pending.push(v) } 
    }) 
}

function BFS(trees,cb){
  let next = []
  let cur = null
  while(trees.length){
    cur = trees.shift() 
    cb(cur.key)
    if(cur.left) next.push(cur.left)
    if(cur.right) next.push(cur.right)
  }
  BFS(next)
}

4.DFS遍历图和二叉树

function DFS(graph,cb){
  const readList = []
  const adjList = graph.adjList
  const vertices = graph.vertices
  function read(vertices){
    vertices.forEach(key=>{
      if(readList.includes(key)) return
      readList.push(key)
      cb(key)
      if(readList.length!==vertices.length) read(adjList.get(key))
    })
  }
}

function DFS(tree,cb){
  if(tree){
    cb(tree.key)
    DFS(tree.left)
    DFS(tree.right)
  }
}