https://www.toutiao.com/a6703121388292538894/

1.图的相关术语

1.1.有一条边相连的顶点叫相邻顶点;

1.2.一个顶点的度就是该顶点的相邻顶点数;

1.3.路径指顶点组成的连续序列;

1.4.简单路径没有重复顶点;

1.5.有向图和无向图

2.图的表示

2.1.邻接矩阵

array[i][j] ===1代表i节点和j节点相邻,否则不相邻

2.2.邻接表

相当于把每个节点的相邻节点一一列举出来。

2.3.关联矩阵

形式和邻接矩阵一样,只是把邻接矩阵的直接维度换成对应的边,适用于边比顶点多的情况。

3.创建图类

接下来就采用邻接表的方式创建上面的图并且采用字典来表示:

3.1.创建字典类

//创建字典类
function Dictionary(){var items = {};//set(key,value)向字典里添加新元素,这里主要用来添加边this.set = function(key,value){items[key] = value;}//has(key)如果存在就返回true,否则falsethis.has = function(key){return key in items;}//get(key)通过key查找特定的数值并返回,这里主要用来查找顶点对应的边数组this.get = function(key){return this.has(key) ? items[key] : undefined;}
}

3.2.创建图类

//创建图类Graph()
function Graph(){var vertices = []; //用来储存顶点var adjList = new Dictionary(); //用来储存边//创建initializeColor用来初始化各个顶点的颜色,为遍历过程中的标记做准备var initializeColor = function(){var color = [];for (var i=0; i<vertices.length; i++){color[vertices[i]] = 'white';}return color;}//addVertex(key)用来添加顶点this.addVertex = function(v){vertices.push(v);adjList.set(v, []);}//addEdge(key,value)用来添加边v-wthis.addEdge = function(v,w){adjList.get(v).push(w);adjList.get(w).push(v);}//toString()把邻接表转化成字符串的形式,便于输出显示this.toString = function(){var s = '';for(var i=0; i<vertices.length; i++){s += vertices[i] + '->';var neighbors = adjList.get(vertices[i]);for(var j=0; j<neighbors.length; j++){s += neighbors[j] + ' ';}s += '
';}return s;}
}

3.3.创建实例

//创建实例
var graph = new Graph();
var myVertices = ['A','B','C','D','E','F','G','H','I'];
//添加顶点
for(var i=0; i<myVertices.length; i++){graph.addVertex(myVertices[i]);
}
//逐一加入边
graph.addEdge('A','B');
graph.addEdge('A','C');
graph.addEdge('A','D');
graph.addEdge('C','G');
graph.addEdge('C','D');
graph.addEdge('D','G');
graph.addEdge('D','H');
graph.addEdge('B','E');
graph.addEdge('B','F');
graph.addEdge('E','I');
console.log(graph.toString());

输出的结果为:

A->B C D

B->A E F

C->A G D

D->A C G H

E->B I

F->B

G->C D

H->D

I->E

4.图的遍历

4.1.广度优先遍历

采用队列的方式,先添加节点的先被探索;

采用三种颜色来反应节点的状态:

白色:还没被访问;

灰色:被访问但未被探索;

黑色:被访问且探索过;

思路:

首先搜索节点A,探索A节点的相邻节点B,C,D,把其加入队列中,再逐一出队列进行探索,从而实现广度遍历。

添加bfs方法

//广度优先遍历,在Graph()类中添加以下方法
this.bfs = function(v, callback){var color = initializeColor(); //初始化节点,都标记为白色var queue = []; //创建队列用来节点的入队;queue.push(v); //访问的节点入队列while(!queue.length==0){ //如果队列非空就执行以下var u = queue.shift(); //节点出队列var neighbors = adjList.get(u); //探索节点对应的边color[u] = 'grey'; //把搜索过的节点变成灰色for (var i=0; i<neighbors.length; i++){ var w = neighbors[i];if(color[w] === 'white'){ //如果探索到的子节点是白色就逐一变灰并入队列color[w] = 'grey';queue.push(w);}}color[u] = 'black'; //节点完成搜索和探索的过程,直接变黑if(callback){ callback(u); //回调函数,可以用来输出}}
}
创建bfs实例//bfs实例
function printNode(value){console.log('Visited vertex:'+value);
}
graph.bfs(myVertices[0],printNode);

bfs输出结果

Visited vertex:A
Visited vertex:B
Visited vertex:C
Visited vertex:D
Visited vertex:E
Visited vertex:F
Visited vertex:G
Visited vertex:H
Visited vertex:I

使用BFS寻找最短路径

this.BFS = function(v){var color = initializeColor(),queue = [],d = [], //用来储存从v到u的距离pred = []; //用来储存节点的前溯点queue.push(v);for(var i=0; i<vertices.length; i++){d[vertices[i]] = 0; //初始化pred[vertices[i]] = null;}while(!queue.length == 0){var u = queue.shift();var neighbors = adjList.get(u);color[u] = 'grey';for (i=0; i<neighbors.length; i++){var w = neighbors[i];if(color[w] === 'white'){color[w] = 'grey';d[w] = d[u]+1; //从头节点到w的距离pred[w] = u;queue.push(w);}} color[u] = 'black';}return{distance:d,predecessers:pred}
}

创建BFS实例

//BFS实例
var shortestPathA = graph.BFS(myVertices[0]);//需要输入头节点myVertices[0]
//console.log(shortestPathA);
//搜索路径BFS
var fromVertex = myVertices[0];
for (var i=1; i<myVertices.length; i++){var toVertex = myVertices[i];var path = []; //path用来储存路径for (var v=toVertex; v!==fromVertex; v=shortestPathA.predecessers[v]){path.push(v);}path.push(fromVertex);var s = path.pop();while(!path.length==0){s += '-' + path.pop();}console.log(s)
}

BFS输出结果

A-B

A-C

A-D

A-B-E

A-B-F

A-C-G

A-D-H

A-B-E-I

4.2.深度优先遍历

采用栈的方式,先添加节点的先被探索;

由递归实现。

思路:

从节点A开始,探索到A的相邻节点B,C,D压入栈中(这里的代码采用for循环,所以没有实质上的栈,但是用栈更容易理解),接着搜索B,探索到B的相邻节点E,F压入栈中,以此递归。

添加dfs方法

this.dfs = function(callback){var color = initializeColor();for (var i=0; i<vertices.length; i++){if(color[vertices[i]]==='white'){dfsVisit(vertices[i], color, callback)//调用递归函数}}
}
var dfsVisit = function(u, color, callback){color[u] = 'grey';if(callback){callback(u);}var neighbors = adjList.get(u);for(var i=0; i<neighbors.length; i++){var w = neighbors[i];if(color[w] === 'white'){dfsVisit(w, color, callback);}}color[u] = 'black';
}

创建dfs实例

graph.dfs(printNode);

dfs输出结果

Visited vertex:A
Visited vertex:B
Visited vertex:E
Visited vertex:I
Visited vertex:F
Visited vertex:C
Visited vertex:G
Visited vertex:D
Visited vertex:H

「数据结构」图基础篇相关推荐

  1. 性能调优之三十六计 —— 「取而代之」Echo/Json 篇

    文章目录 性能调优之三十六计 -- 「取而代之」Echo/Json 篇 Echo 高性能.极简框架 C.JSON Json-iterator Q&A 附录 性能调优之三十六计 -- 「取而代之 ...

  2. 「网络安全」安全设备篇(1)——防火墙

    什么是防火墙? 防火墙是指设置在不同网络(如可信任的企业内部网和不可信的公共网)或网络安全域之间的一系列部件的组合.它可以通过监测.限制.更改跨越防火墙的数据流,尽可能地对外部屏蔽网络内部的信息.结构 ...

  3. 「网络安全」安全设备篇(7)——抗DDOS产品

    概述 DDOS攻击随着互联网的快速发展,日益猖獗,从早期的几兆.几十兆,到现在的几十G.几十T的流量攻击,形成了一个很大的利益链.DDOS攻击由于容易实施.难以防范.难以追踪,成为最难解决的网络安全问 ...

  4. 「网络安全」安全设备篇(3)——IPS

    什么是IPS? IPS是英文"Intrusion Prevention Systems"的缩写,中文意思是"入侵防御系统",IPS实现实时检查和阻止入侵. 上文 ...

  5. 「数据结构」普林斯顿算法课第二周作业

    「数据结构」普林斯顿算法课第二周作业 Algorithm I, Princeton 编程作业: Deques and Randomized Queues 思路 Deque.java Randomize ...

  6. 2021年「资料员」-通用基础及岗位技能(资料员)考试资料

    来源:百分百题库[公众号][小程序] 资料员岗位技能(资料员)模拟考试及资料员题库,包含(资料员)模拟考试答案解析及(资料员)模拟考试系统练习.由百分百题库公众号结合国家资料员大纲最新题库,有助于资料 ...

  7. 「网络安全」安全设备篇(4)——防火墙、IDS、IPS的区别

    前面三篇文章,针对防火墙.IDS.IPS做了详细介绍,具体内容这里不再赘述,感兴趣的小伙伴可以去看看哦. 概念不同 防火墙和IPS属于访问控制类产品,而IDS属于审计类产品.我们可以用一个简单的比喻, ...

  8. 思维导图 基础篇(14)应用-阅读书籍

    系列文章解读&说明: 本系列文章主要内容是 思维导图 基础课,旨在帮助更多 热爱学习的伙伴 更具体的了解思维导图,同时也会让 更多的伙伴从 思维导图 认知 误区中走出. 系列文章总纲链接为:专 ...

  9. 「数据结构」普林斯顿算法课第一周作业

    「数据结构」普林斯顿算法课第一周作业 Algorithm I, Princeton 编程作业: Percolation 思路 第一部分代码展示 第二部分代码展示 编程作业: Percolation P ...

最新文章

  1. 几十年的领域专家告诉你,机器翻译进化到哪一步了?
  2. docker对数据卷进行还原操作
  3. S3c2410_SDIO_调试笔记二
  4. python random 和numpy random_Python中numpy.random和random.random之间的区别
  5. 计算机系统的可靠性可以用什么来表示,系统分析师考试计算机系统的可靠性指标...
  6. 漫画:什么是鸡尾酒排序
  7. 前端学习(2772):uni图片预览
  8. Document API
  9. android图片垂直居中,img图片在div里垂直居中的最佳解决方案
  10. linux系统关闭指定服务的方式
  11. 英文简历模板计算机专业,2016年计算机专业英文简历模板
  12. 【asp.net】VS 2008中文版下载
  13. 22_多点电容触摸屏驱动
  14. ORACLE-EBS常用表
  15. 微信小程序+轮播图+弹窗等设置
  16. python 招聘 海盐_聚焦普高新课标 提升信息核心素养——海盐县初中信息技术Python课堂教学研讨活动在武原中学举行...
  17. java虚拟机学习笔记之垃圾收集(上)
  18. 记录_20190626
  19. jquery 添加transform样式
  20. HTML+CSS系列教程

热门文章

  1. 阿里全球数学竞赛第二届
  2. 中科院韩先培:预训练模型怎样成为下一代知识图谱
  3. Yann LeCun最新文章:自监督学习的统一框架
  4. 超速电眼:全时成像芯片重塑机器视觉
  5. 尤雨溪携手字节前端专家,畅聊 Vue 3.0 前端技术新趋势
  6. XGBoost调参技巧(二)Titanic实战Top9%
  7. 独家 | 感悟注意力机制
  8. 【经典书】随机矩阵理论与无线网络
  9. 中国工业机器视觉产业发展白皮书(附ppt)
  10. 【斯坦福大学】可信任机器学习课程,附课件