图的广度和深度优先搜索

162 阅读1分钟

图与树,链表的区别

链表是线性数据结构,常见的链表有单向链表,双向链表,有环链表。

image.png

image.png

image.png

链表的每个元素都有一个next指针,指向下一个元素。双向两边还有一个previous指针,指向上一个元素。这类似我们在一个网站上注册账号信息一样,可以点击下一步,也可以点击上一步。

树结构有很多种,二叉树,234树,红黑树等等。

image.png 树有个很明显的特点就是,每个节点都可以找到他的子节点,但是从子节点却不能找到他的父节点。每个节点都可以被当做根节点。而且不能有环。

再看图结构

image.png 有环无向,或者说是双向。 看起来也是乱七八糟的。图还有一个名字叫拓补结构。

图的深度优先搜索DFS

图的DFS和树不同,因为图有环而树没得。

function Node(value){
  this.value = value;
  this.neighbor = [];
}

const a = new Node('A'),
      b = new Node('B'),
      c = new Node('C'),
      d = new Node('D'),
      e = new Node('E');
a.neighbor.push(b,c);
b.neighbor.push(a,c,d);
c.neighbor.push(a,b,d);
d.neighbor.push(b,c,e);
e.neighbor.push(d);

function search(node, target, path = []){
  if(node === null) {
    return false;
  }
  if (path.includes(node)) {
    false
  }
  path.push(node);
  if(node.neighbor.length === 0) {
    return false;
  }
  if(node.value === target) {
    return true;
  }
  let result = false;
  for (const item of node.neighbor) {
    result = search(item, target, path) 
  }
  return result;
}

图的广度优先搜素BFS

思路就是给点一个节点,判断节点是否相等,如果不相等, 收集这个节点的所有邻居,递归邻居查找

function bsf(nodes, target, path = []){
  if(nodes.length === 0 || nodes === null) {
    return false;
  }
  const neighbors = []
  for (const item of nodes) {
    if(path.includes(item)){
      continue;
    } else {
      path.push(item)
      if(item.value === target) {
        return true;
      } else {
        neighbors.push(...item.neighbor);
      }
    }
  }
  return bsf(neighbors, target, path)
}