专栏首页zaking's用js来实现那些数据结构15(图01)

用js来实现那些数据结构15(图01)

  其实在上一篇介绍树结构的时候,已经有了一些算法的相关内容介入。而在图这种数据结构下,会有更多有关图的算法,比如广度优先搜索,深度优先搜索最短路径算法等等。这是我们要介绍的最后一个数据结构。同时也是本系列最为复杂的一个。那么我们先来简单介绍一下,什么是图?

一、图的概念

  简单说,就是网络结构的抽象模型,图是一组由连接的节点(或顶点)。任何二元关系都可以用图来表示。比如我们的地图,地铁线路图等。都是图的实际应用。

  接着我们看看图的一些相关概念和术语。

  一个图G = (V,E)由以下元素组成:

    V:一组顶点。

    E:一组边,链接V中的顶点。

  在继续之前我们先来上张图,继续我们的看图说话。

   请看上图,我们来解释一些概念。

    1、由一条边连接在一起的顶点称为相邻顶点。比如上图中的A和B,A和C,A和D都是相邻的,但是A和E不是相邻的。

    2、一个顶点的取决于其相邻顶点的数量。也就是说,有多少个顶点与其相连,那么它的度就是多少。比如A的度是3,D的度就是4。

    3、路径是顶点V1,V2.....Vn的一个连续序列,其中Vi和Vi+1是相邻的。比如上图中的ACDG,ABEI都是一个路径。

    4、简单路径要求不包含重复的定点。比如ADG就是一条简单路径。

    5、除去最后一个顶点(因为它和第一个顶点时相同的),也是一个简单路径,比如ADCA。

    6、如果图中不存在环。则该图是无环的。

    7、如果图中每两个顶点间都存在路径,则该图是连通的。

  为了便于对比,我又花了一张图。

  跟第一幅图几乎是一样的,只不过我们在路径上加了点东西。

    8、图可以是有向的(边有方向)或者是无向的(边没有方向)。比如上图我们在边上加了方向就变成了有向图。

    9、如果在图中的两个顶点间在双向上都存在路径,则该图是强连通的。比如上图中我们可以说C和D是强连通的。A和B不是强连通的。但是上图并不是一个强连通图。因为上图并不是两个点都有双向的路径。

    10、图还可以是未加权的或是加权的。上图边上加的数字就是加权值。(加权的意思可以简单理解为CSS选择器中的那种权重。)

二、图的表示方法

  我们可以表示图的方法有很多。根据我们要解决问题的类型和图的类型。我们可以选择不同的方法来表示图。下面我们会简单介绍两种表示图的方法。

  1、邻接矩阵。每一个节点都和一个整数相关联,该整数将作为数组的索引。我们用一个二维数组来表示各个顶点之间的连接情况。比如索引为i的节点和索引为j的节点相邻,则表示为arrya[i][j]=1。否则arrya[i][j]=0。

  邻接矩阵看起来就是这样子的。要注意我们上面的邻接矩阵只是表示两个顶点是否相邻。我们还需要一个数组来存储所有的顶点。

  但是邻接矩阵会有一些性能问题。比如我们会用很多的空间来表示一些根本就不存在的边。比如上图所有的0。再比如我们想要找到A顶点的相邻顶点,即使A顶点只有一个相邻顶点。我们也必须遍历整个数组才能找到。

2、邻接表,鉴于以上的问题。我们在本篇中所使用的图的表示方法就是邻接表。邻接表由图中每个顶点的相邻顶点列表所组成。我们可以用数组,链表,map或者hashMap来实现邻接表。

  邻接表看起来就像是上图这样。

  那么我们知道了图的一些基本概念和我们要使用的图的表示方法。下面我们先来完成我们Graph类的架子。

function Map () {
    //......其他各种方法,详见前面的字典部分
}

//代码很简单,但是还是要解释一下。
function Graph() {
    //vertices数组存放我们图中所有的顶点
    var vertices = [];
    //adjList存放我们的邻接表。adjList会使用顶点来作为键,邻接顶点列表作为值
    var adjList = new Map();
    //添加顶点的方法。
    this.addVertices = function (v) {
        //存放到顶点数组中
        vertices.push(v);
        //生成一个还没有邻接顶点列表的Map,因为这时我们已经有顶点了,所以要生成以待使用
        adjList.set(v,[]);
    }
    //这里有个小细节我们需要注意,哦对,这是为图添加边的方法。要注意的是,实际上,在代码中,我们是没有一个东西(变量或者其他什么)来代表边的。
    //我们为两个顶点之间添加一个边实际上只是为两个顶点的邻接表中加入彼此。这样就代表了这两个顶点是相邻的。
    this.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 += '\n';
        }
        return s;
    }
}

//我们来试一下
var graph = new Graph();

var verticesArray = ['A','B','C','D','E','F','G','H','I'];

for(var i = 0; i < verticesArray.length; i++) {
    graph.addVertices(verticesArray[i]);
}

graph.addEdge('A','B');
graph.addEdge('A','C');
graph.addEdge('A','D');
graph.addEdge('C','D');
graph.addEdge('C','G');
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  D  G  
D->A  C  G  H  
E->B  I  
F->B  
G->C  D  
H->D  
I->E  
*/

  那么我们就实现了Graph类中最简单的部分——如何添加顶点和边。大家会不会觉得有点简单了。嘿嘿.....有趣的还在后面,别急......

  好了,那么到这里这篇文章就结束了。下一篇文章我们再继续学习图的遍历。

  最后,由于本人水平有限,能力与大神仍相差甚远,若有错误或不明之处,还望大家不吝赐教指正。非常感谢!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 走进webpack(2)--第三方框架(类库)的引入及抽离

      正文之前,由于这是一个系列的文章,可能第一次看到的看官老爷们会觉得突兀,如果你是webpack新手,我建议你先从前几篇文章看起,如果你对webpack有一些...

    zaking
  • 用js来实现那些数据结构16(图02-图的遍历)

    zaking
  • 用js来实现那些数据结构16(图02-图的遍历)

    zaking
  • 图论(一)

    图论(Graph theory)是数学的一个分支,它以图为研究对象,研究顶点和边组成的图形的数学理论和方法。

    每天学Java
  • 浅谈什么是图拓扑排序

      在工程实践中,一个工程项目往往由若干个子项目组成。这些子项目间往往有两种关系:   (1) 先后关系,即必须在某个项完成后才能开始实施另一个子项目。   (...

    五分钟学算法
  • 数据结构-图

    图是不同于前面两种数据结构的另一种新的数据结构,线性表中元素与元素之间是被串起来的,每个数据元素只有一个直接前驱和一个直接后继,是一种一对一的数据结构;在树的结...

    张俊红
  • 浅谈图的深度优先遍历

    Zoctopus
  • 数据结构学习笔记(图)

    希希里之海
  • 干货 | 数据结构之图论基础

    数据结构是程序的核心之一,可惜本公众内关于数据结构的文章略显不足,于是何小编打算与向柯玮小编一起把数据结构这部分补齐,来满足各位观众大老爷。

    短短的路走走停停
  • 数据结构基础温故-5.图(上):图的基本概念

    前面几篇已经介绍了线性表和树两类数据结构,线性表中的元素是“一对一”的关系,树中的元素是“一对多”的关系,本章所述的图结构中的元素则是“多对多”的关系。图(Gr...

    Edison Zhou

扫码关注云+社区

领取腾讯云代金券