「数据结构」图基础篇
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
「数据结构」图基础篇相关推荐
- 性能调优之三十六计 —— 「取而代之」Echo/Json 篇
文章目录 性能调优之三十六计 -- 「取而代之」Echo/Json 篇 Echo 高性能.极简框架 C.JSON Json-iterator Q&A 附录 性能调优之三十六计 -- 「取而代之 ...
- 「网络安全」安全设备篇(1)——防火墙
什么是防火墙? 防火墙是指设置在不同网络(如可信任的企业内部网和不可信的公共网)或网络安全域之间的一系列部件的组合.它可以通过监测.限制.更改跨越防火墙的数据流,尽可能地对外部屏蔽网络内部的信息.结构 ...
- 「网络安全」安全设备篇(7)——抗DDOS产品
概述 DDOS攻击随着互联网的快速发展,日益猖獗,从早期的几兆.几十兆,到现在的几十G.几十T的流量攻击,形成了一个很大的利益链.DDOS攻击由于容易实施.难以防范.难以追踪,成为最难解决的网络安全问 ...
- 「网络安全」安全设备篇(3)——IPS
什么是IPS? IPS是英文"Intrusion Prevention Systems"的缩写,中文意思是"入侵防御系统",IPS实现实时检查和阻止入侵. 上文 ...
- 「数据结构」普林斯顿算法课第二周作业
「数据结构」普林斯顿算法课第二周作业 Algorithm I, Princeton 编程作业: Deques and Randomized Queues 思路 Deque.java Randomize ...
- 2021年「资料员」-通用基础及岗位技能(资料员)考试资料
来源:百分百题库[公众号][小程序] 资料员岗位技能(资料员)模拟考试及资料员题库,包含(资料员)模拟考试答案解析及(资料员)模拟考试系统练习.由百分百题库公众号结合国家资料员大纲最新题库,有助于资料 ...
- 「网络安全」安全设备篇(4)——防火墙、IDS、IPS的区别
前面三篇文章,针对防火墙.IDS.IPS做了详细介绍,具体内容这里不再赘述,感兴趣的小伙伴可以去看看哦. 概念不同 防火墙和IPS属于访问控制类产品,而IDS属于审计类产品.我们可以用一个简单的比喻, ...
- 思维导图 基础篇(14)应用-阅读书籍
系列文章解读&说明: 本系列文章主要内容是 思维导图 基础课,旨在帮助更多 热爱学习的伙伴 更具体的了解思维导图,同时也会让 更多的伙伴从 思维导图 认知 误区中走出. 系列文章总纲链接为:专 ...
- 「数据结构」普林斯顿算法课第一周作业
「数据结构」普林斯顿算法课第一周作业 Algorithm I, Princeton 编程作业: Percolation 思路 第一部分代码展示 第二部分代码展示 编程作业: Percolation P ...
最新文章
- 几十年的领域专家告诉你,机器翻译进化到哪一步了?
- docker对数据卷进行还原操作
- S3c2410_SDIO_调试笔记二
- python random 和numpy random_Python中numpy.random和random.random之间的区别
- 计算机系统的可靠性可以用什么来表示,系统分析师考试计算机系统的可靠性指标...
- 漫画:什么是鸡尾酒排序
- 前端学习(2772):uni图片预览
- Document API
- android图片垂直居中,img图片在div里垂直居中的最佳解决方案
- linux系统关闭指定服务的方式
- 英文简历模板计算机专业,2016年计算机专业英文简历模板
- 【asp.net】VS 2008中文版下载
- 22_多点电容触摸屏驱动
- ORACLE-EBS常用表
- 微信小程序+轮播图+弹窗等设置
- python 招聘 海盐_聚焦普高新课标 提升信息核心素养——海盐县初中信息技术Python课堂教学研讨活动在武原中学举行...
- java虚拟机学习笔记之垃圾收集(上)
- 记录_20190626
- jquery 添加transform样式
- HTML+CSS系列教程