什么是图?

图是一种复杂的非线性表结构.由若干给定的点一级任意两点间的连线所构成.图通常用来描述事物之间的特定关系, 代表的就是事物, 线就是事物之间所具有的关系.例如社交网络就是一种典型的图关系, 每一个用户都是一个顶点,任意两个用户加了好友, 他们之间就有了一条边.

简单总结下, 图就是由顶点(vertex)边(edge)组成.

除此而外, 图中还有度的概念, 和顶点相连的边数就称为度. 如果用微信来类比的话, 我们自己本身就是一个顶点, 我们微信中的好友个数, 就是度.

有向图中, 度又被分为入度(In-degree)出度(Out-degree). 入度指的是有多少个边指向这个顶点, 而出度指的是有多少个边以此顶点为 起点 指向其他的顶点.这种情况可以用微博来类比下, 你被多少人关注了就是入度, 你关注了多少人就是出度.

还有一种带权图, 每条边都会被分配一个权重(weight), 权重可以用来表示边之间的比较关系.比如时间更短, 道路状况更加良好等等.

图的存储

  • 邻接矩阵存储
    邻接矩阵的存储, 实际上使用的是一个二维数组. 在无向图的存储中, 如果顶点 i 和 j 之间有一条边, 那么我们就将 Array [ i ] [ j ] 和 Array [ j ] [ i ] 都标记为 1. 如果是有向图, i → j, 则 Array [ i ] [ j ] 标记为 1, 反之亦然. 带权图中, 数组存储对应的权重.
    邻接矩阵存储图虽然很直观, 但是浪费空间. 在无向图中, 如果 Array [ i ] [ j ] 被标记为 1, 那么 Array [ j ] [ i ] 也必然为 1.这样我们就有一半的空间浪费掉了. 而对于顶点多, 边少的稀疏图来说, 浪费则可能更加严重.
    但它也有自己的优点, 因为是基于数组的, 所以查找两条边的关系时非高效, 还有可以将很多图的运算转换成矩阵之间的运算.
  • 邻接表存储
    邻接表其实有点像散列表.

图中的每一个顶点都存储一条链表, 链表中存储的是所有与它相连的顶点.

邻接表虽然在存储上节省了空间, 但在查找上却比邻接矩阵耗时.

深度优先搜索

图的搜索算法, 最直接的理解就是从某个顶点出发, 到另一个顶点的最短路径. 深度优先搜索和广度优先搜索是其中最简单最暴力的两种.

理解深度优先搜索算法最简单就是把它想象成是在走迷宫, 我们从入口开始出发, 每遇到一个岔口, 就选择其中一个, 如果有路就一直走, 直到到达目的地. 如果没有路了, 就返回上一个岔路, 重新选择一条路.

深度优先搜索使用的就是回溯思想.

class Graph {constructor(v) {this.adj = new Map()this.v = vfor (let i = 0; i < v; i++) {this.adj.set(i, [])}}addEdge(s, t) {this.adj.get(s).push(t)this.adj.get(t).push(s)}getAdj() {return this.adj}
}

这里我们使用邻接表来存储图. 用深度递归来寻找 s 到 t 的最短路径.

class Graph {......DFS(s, t) {const prev = new Array(this.v).fill(-1) // 存储访问过的路径const visited = new Array(this.v) // 存储已经访问过的节点, 避免重复访问let isFound = false // 是不是已经找到visited[s] = truethis.recurse(s, t, prev, visited, isFound)printPrev(prev, s, t)}recurse(s, t, prev, visited, isFound) {if (isFound) {return}visited[s] = trueif (s === t) {isFound = truereturn}let curr = this.adj.get(s)for (let i = 0; i < curr.length; i++) {let q = curr[i]if (!visited[q]) {visited[q] = truethis.recurse(q, t, prev, visited, isFound)}}}
}

广度优先搜索

广度优先搜索是一种像水波一样的从中心向外扩散的策略. 从起点开始先寻找离它最近的点(可能是多个), 然后是次近的, 直到找到为止.

class Graph{......BFS(s, t) {if (s === t) {return}const prev = new Array(this.v).fill(-1) // 存储访问路径const queue = [] // 存储已经访问, 但相邻顶点还没有被访问的顶点. 只有访问完 k 层的所有顶点, 才能访问第 k+1 层的.const visited = [] // 用来存储已经被访问过的顶点, 避免重复访问let isFinised = falsequeue.push(s)visited[s] = truewhile (queue.length !== 0 && !isFinised) {let w = queue.shift()let curr = this.adj.get(w)for (let i = 0; i < curr.length; i++) {let q = curr[i]if (!visited[q]) {prev[q] = wif (q === t) {isFinised = truebreak}visited[q] = truequeue.push(q)}}}if (isFinised) {printPrev(prev, s, t) //打印路径} else {console.log('not found')}}
} 

深度优先遍历和广度优先遍历_图与深度优先搜索和广度优先搜索相关推荐

  1. 广度优先搜索生成树怎么画_图的深度优先遍历与广度优先遍历以及最小生成树...

    图的深度优先遍历 题目:写出附从每个顶点出发的一次深度优先搜索遍历序列.在纸上画出遍历过程和序列,提交截图. 错误回答 从A点开始遍历:0124-01324-0134-0324-034 从B点开始遍历 ...

  2. 图的深度优先遍历和广度优先遍历_图的深度优先遍历(DFS)与广度优先遍历(BFS)的c语言实现...

    头文件 #pragma warning( disable : 4996)#pragma once#ifndef _GRAPH_H_#define _GRAPH_H_ #define MAX_VERTE ...

  3. dfs深度优先搜索_图的深度优先搜索(DFS)

    dfs深度优先搜索 Depth First Search (DFS) is an algorithm that searches a graph/tree, in a depth-wise manne ...

  4. bfs广度优先搜索算法_图的广度优先搜索(BFS)

    bfs广度优先搜索算法 What you will learn? 您将学到什么? How to implement Breath first search of a graph? 如何实现图的呼吸优先 ...

  5. 数据结构学习笔记——图的遍历算法(深度优先搜索和广度优先搜索)

    目录 一.图的遍历概念 二.深度优先搜索(DFS) (一)DFS算法步骤 1.邻接表DFS算法步骤 2.邻接矩阵DFS算法步骤 (二)深度优先生成树.森林 (三)DFS的空间复杂度和时间复杂度 三.广 ...

  6. java数据结构和算法——图的深度优先(DFS)遍历

    目录 一.图的遍历介绍 二.图的深度优先搜索(Depth First Search) 三.图的深度优先遍历算法步骤 四.图的深度优先遍历示例需求 五.图的深度优先遍历代码示例 一.图的遍历介绍 所谓图 ...

  7. 图的深度优先遍历和宽度优先遍历C语言,图的广度、深度优先遍历 C语言

    以下是老师作为数据结构课的作业的要求,没有什么实际用处和可以探讨和总结的的地方,所以简单代码直接展示. 宽度优先遍历: #include #include #include using namespa ...

  8. 图的深度优先搜索及拓扑排序

    本文将介绍图的深度优先搜索,并实现基于深度优先搜索的拓扑排序(拓扑排序适用于有向无环图,下面详细介绍). 1. 图的深度优先遍历要解决的问题 图的深度优先搜索与树的深度优先搜索类似,但是对图进行深度优 ...

  9. 图之深度优先生成森林

    生成森林是指由非连通图的连通分量的生成树所组成的森林,而深度优先生成森林则指由图的深度优先遍历算法获得的生成森林. 下面给出非连通图的深度优先生成森林算法的Java实现,其中生成森林采用孩子兄弟链表存 ...

最新文章

  1. 10 个最值得 Python 新人练手的有趣项目
  2. 再谈MySQL JSON数据类型
  3. 搞懂这些SQL优化技巧,面试横着走
  4. Spring事务管理--嵌套事务详解
  5. 【渝粤题库】国家开放大学2021春2617生产与运作管理题目
  6. oracle to char trim,to_char前面多出空格
  7. 【FFMPE系列】之FFMPEG常用命令
  8. diff命令两个服务器文件,LINUX命令diff-文件管理-比较给定的两个文件的不同
  9. Java 常见的面试题(反射)
  10. 微信开发工具调试窗口怎样查看netWork
  11. Java、JSP新华书店网上售书系统
  12. 架构图、用例图、流程图、时序图、类图
  13. 如何写 peer review
  14. pv是什么意思?增长方法有哪些!
  15. 一个手机号可注册两个微信号
  16. win10连接filco蓝牙键盘
  17. RK988键盘切换蓝牙模式
  18. Redis订阅与发布原理
  19. 腾讯云Centos安装python3教程
  20. 多线程的三种设计模式的介绍

热门文章

  1. 打擦边球,涨粉1700万!中国最“不正经”的官媒,比杜蕾斯还会玩
  2. 知乎回应“腾讯搜狗退出知乎股东”:是上市后的标准操作
  3. 法拉第未来宣布汉福德工厂获得最终生产使用资质
  4. iPhone 13将减产1000万部,因特定芯片供应不足
  5. iPhone 13及12推动,机构预计苹果今年将销售近2亿部5G iPhone
  6. 网易丁磊:给我100个亿,也不会躺平
  7. 蚂蚁集团CEO胡晓明宣布辞任
  8. iQOO Z1于10月21日开启双十一钜惠,最高立减200元
  9. 国内首家生鲜电商平台要凉了:阿里曾参投,7月底已申请破产重组
  10. 价值12万汽车网上售价1万?老哥拍下后4S店不认账:标错价了