图分为无向图和有向图

图的存储结构有邻接矩阵、邻接表、十字链表、邻接多重表这四种,最常用的是前两种

本篇主要是利用邻接矩阵实现无向图的创建和遍历(深度优先、广度优先),深度优先其实就是二叉树里的前序遍历

  

利用邻接矩阵(边数组)创建图

let scanf = require('scanf');
//定义邻接矩阵
let Arr2 = [
[0, 1, 0, 0, 0, 1, 0, 0, 0],
[1, 0, 1, 0, 0, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 0, 0, 0, 1],
[0, 0, 1, 0, 1, 0, 1, 1, 1],
[0, 0, 0, 1, 0, 1, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 0, 0, 1, 1, 0, 1, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0],
] let numVertexes = 9, //定义顶点数
numEdges = 14; //定义边数 // 定义图结构
function MGraph() {
this.vexs = []; //顶点表
this.arc = []; // 邻接矩阵,可看作边表
this.numVertexes = null; //图中当前的顶点数
this.numEdges = null; //图中当前的边数
}
let G = new MGraph(); //创建图使用 //创建图
function createMGraph() {
G.numVertexes = numVertexes; //设置顶点数
G.numEdges = numEdges; //设置边数 //录入顶点信息
for (let i = 0; i < G.numVertexes; i++) {
G.vexs[i] = scanf('%s'); //String.fromCharCode(i + 65); ascii码转字符
}
console.log(G.vexs) //打印顶点 //邻接矩阵初始化
for (let i = 0; i < G.numVertexes; i++) {
G.arc[i] = [];
for (j = 0; j < G.numVertexes; j++) {
G.arc[i][j] = Arr2[i][j]; //INFINITY;
}
} /**以下是手动录入的方式 */
// for (let k = 0; k < G.numEdges; k++) {
// console.log('输入边(vi,vj)上的下标i,下标j和权w:');
// let rlt = scanf('%d,%d,%d');
// let i = rlt[0], j = rlt[1], w = rlt[2];
// G.arc[i][j] = w;
// G.arc[j][i] = G.arc[i][j]; //无向图,矩阵对称
// } console.log(G.arc); //打印邻接矩阵
}

深度优先遍历

let visited = []; //访问标志数组,遍历时使用

//邻接矩阵的深度优先递归算法
function DFS(i) {
visited[i] = true;
console.log('打印顶点:', G.vexs[i]) //打印顶点 ,也可以其他操作
for (let j = 0; j < G.numVertexes; j++) {
if (G.arc[i][j] == 1 && !visited[j]) {
console.log(G.vexs[i], '->', G.vexs[j])
DFS(j) //对未访问的顶点进行递归
}
}
}
//邻接矩阵的深度遍历操作
function DFSTraverse() {
for (let i = 0; i < G.numVertexes; i++) {
visited[i] = false;
}
for (let i = 0; i < G.numVertexes; i++) {
if (!visited[i])
DFS(i)
}
}

广度优先遍历

//邻接矩阵的广度遍历算法
function BFSTraverse() {
let queue = []; //初始化队列
for (let i = 0; i < G.numVertexes; i++) {
visited[i] = false;
}
for (let i = 0; i < G.numVertexes; i++) { //对每一个顶点做循环
if (!visited[i]) { //如果没有访问过就处理
visited[i] = true;
console.log('打印顶点:', G.vexs[i]) //也可以是其他操作
queue.push(i); //将此顶点入队列
while (queue.length != 0) { //当前队列不为空
queue.shift();
for (let j = 0; j < G.numVertexes; j++) {
//判断其他顶点若与当前顶点存在边且未访问过
if (G.arc[i][j] == 1 && !visited[j]) {
visited[j] = true;
console.log(G.vexs[i], '->', G.vexs[j])
console.log('打印顶点:', G.vexs[j])
queue.push(j) //将此顶点放入队列
}
}
}
}
}
}

运行:

console.log('**********创建图结构**********');
createMGraph();
console.log('**********广度优先遍历**********');
DFSTraverse();
console.log('**********广度优先遍历**********');
BFSTraverse();

结果:

JS实现图的创建和遍历的更多相关文章

  1. 图的创建和遍历(BFS/DFS)

    图的表示方法主要有邻接矩阵和邻接表.其中邻接表最为常用,因此这里便以邻接表为例介绍一下图的创建及遍历方法. 创建图用到的结构有两种:顶点及弧 struct ArcNode { int vertexIn ...

  2. JS DOM操作(创建、遍历、获取、操作、删除节点)

    创建节点 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="u ...

  3. JS实现二叉树的创建和遍历

    1.先说二叉树的遍历,遍历方式: 前序遍历:先遍历根结点,然后左子树,再右子树 中序遍历:先遍历左子树,然后根结点,再右子树 后续遍历:先遍历左子树,然后右子树,再根结点   上代码:主要还是利用递归 ...

  4. 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。

    //归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...

  5. 【算法导论】图的深度优先搜索遍历(DFS)

    关于图的存储在上一篇文章中已经讲述,在这里不在赘述.下面我们介绍图的深度优先搜索遍历(DFS). 深度优先搜索遍历实在访问了顶点vi后,访问vi的一个邻接点vj:访问vj之后,又访问vj的一个邻接点, ...

  6. 【算法导论】图的广度优先搜索遍历(BFS)

    图的存储方法:邻接矩阵.邻接表 例如:有一个图如下所示(该图也作为程序的实例): 则上图用邻接矩阵可以表示为: 用邻接表可以表示如下: 邻接矩阵可以很容易的用二维数组表示,下面主要看看怎样构成邻接表: ...

  7. JS前端图形化插件之利器Gojs组件(php中文网)

    JS前端图形化插件之利器Gojs组件(php中文网) 一.总结 一句话总结:php中文网我可以好好走一波 二.JS前端图形化插件之利器Gojs组件 参考: JS前端图形化插件之利器Gojs组件-js教 ...

  8. JS对象—数组总结(创建、属性、方法)

    JS对象—数组总结(创建.属性.方法) 1.创建字符串 1.1 new Array() var arr1 = new Array(); var arr2 = new Array(6); 数组的长度为6 ...

  9. js正则表达式图形化工具-rline

    github地址:https://github.com/finance-sh/rline 在线demo: http://lihuazhai.com/demo/test.html 这是一个js正则表达式 ...

随机推荐

  1. MVC框架入门准备(一)

    最近开发一套自己的框架,开发了一个多月,已传到git,学到了挺多,系列文章我会慢慢写挺多 这里先讲大致框架多用到的某些函数,我这里先列举一部分,网上对函数的定义,参数说明等,我就不照搬了,记录自己的理 ...

  2. (转)科普:SATA、PCIe、AHCI、NVMe

    原文链接:https://forum.51nb.com/thread-1670848-1-1.html IT 界总喜欢发明新名词.而且同一个东西,可能有几个不同的名字.同一个名字,又可能指不同的东西. ...

  3. Git 教程 -- 基于自己学习记录

    Git 教程 -- 基于自己学习记录 1. 引言 由于学校布置了一项熟悉 git 和 svn 操作的实验,所以自己重新温习了下 git,记录过程在这. 2. 注册登录 GitHub. 3. 选择一个仓 ...

  4. Thread.sleep(1000)

    public class Wait { public static void main(String[] args) { System.out.println(System.currentTimeMi ...

  5. zTree第四章,异步加载,后端

    后端 ------------------------------------------------------------------------------------------------- ...

  6. BZOJ3729: Gty的游戏(伪ETT)

    题面 传送门 前置芝士 巴什博奕 \(Nim\)游戏的改版,我们现在每次最多只能取走\(k\)个石子,那么\(SG\)函数很容易写出来 \[SG(x)=mex_{i=1}^{\min(x,k)}SG( ...

  7. 爬虫4:re库

        一. 常见匹配模式   模式 描述 \w 匹配字母数字及下划线 \W 匹配非字母数字下划线 \s 匹配任意空白字符,等价于 [\t\n\r\f]. \S 匹配任意非空字符 \d 匹配任意数字, ...

  8. Visual Studio进行负载测试,RIG和负载测试术语- Part II

    对于一个多用户的应用程序,性能是非常重要的.性能不仅是执行的速度,它包括负载和并发方面.Visual Studio是可以用于性能测试的工具之一.Visual Studio Test版或Visual S ...

  9. Keras2.2 predict和fit_generator的区别

    1.使用predict时,需设置batch_size 查看keras文档中,predict函数原型:predict(self, x, batch_size=32, verbose=0) 说明:只使用b ...

  10. Java多线程笔记[未更新完]

    最近课上可摸鱼时间较多,因此并发开坑学习 本篇学习自Java多线程编程实战指南 目前进展:刚开坑,处于理解概念阶段 本篇学习自Java多线程编程实战指南 Q.进程和线程的区别 进程Process是程序 ...