数据结构-图:JavaScript语言描述

图的定义

图由边的集合与顶点的集合组成。如果一个图的定点对是有序的则称为有向图。对有向图的顶点对排序后,可以在两个顶点之间绘制一个箭头。有向图表明了顶点的流向。
如果图是无序的则称为无序图或无向图。图中的一系列顶点构成路径,路径中的顶点都由边连接。路径的长度用第一个顶点到最后一个顶点之间边的数量表示。
由指向自身的顶点组成的路径称为环,环的长度为0。
圈是至少有一条边的路径,且路径的第一个顶点和最后一个顶点相同。没有重复顶点和重复边的圈就是一个简单的圈。除了第一个和最后一个顶点外,路径中有其他重复的顶点的圈称为平凡圈。
如果两个顶点之间有路径连通,那么这两个顶点称为强连通。
如果有向图的顶点都是强连通的那么这个图也是强连通的。

用图对现实中的系统建模

表示边

我们将表示图的边的方法称为邻接表或邻接表数组。将边表示为有顶点的相邻顶点列表构成的数组,并以此顶点作为索引。
邻接矩阵,是一个二维数组,其中的元素表示两个顶点间是否有一条边。
用一个长度与顶点数量相同的数组记录顶点,为每个元素创造一个子数组,记录相邻顶点的数量。

function Map(v) {
    this.vertices = v;// 结点的总数量
    this.edges = 0;
    this.adj = [];
    this.edgeTo = [];
    this.marked = [];
    for(let i = 0; i < this.vertices; i++){
        this.adj[i] = [];
        this.adj[i].push('');
    }
    for(let i = 0; i < this.vertices; i++){
        this.marked[i] = false;
    }
    
}

Map.prototype.addEdge = function (v,w){
    this.adj[v].push(w);
    this.adj[w].push(v);
    this.edges++;
}

Map.prototype.show = function () {
    for(let i = 0; i < this.vertices; i++){
        for(let j = 0; j < this.vertices; j++){
            if(this.adj[i][j] !== undefined){
                console.log(this.adj[i][j])
            }
        }
    }
}
Map.prototype.pathTo = function (v) {
    var source = 0;
    if (!this.hasPathTo(v)) {
        return undefined;
    }
    var path = [];
    for (var i = v; i != source; i = this.edgeTo[i]) {
        path.push(i);
    }
    path.push(s);
    return path;
}
Map.prototype.hasPathTo =  function (v) {
     return this.marked[v];
}

搜索图

从一个指定的顶点可以到达那些顶点。

深度优先搜索

从起始顶点开始追溯,直到到达最后一个顶点,然后回溯,开始追溯下一条路径直到到达最后的顶点,如此往复,直到没有路径为止。

Map.prototype.dfs = function (v) {
    this.marked[v] = true;
    if(this.adj[v] !== undefined){
        for(let key in this.adj[v]){
            if(!this.marked[key]){
                this.dfs[key];
            }
        }
    }
}

广度优先搜索

从第一个顶点开始,尝试访问尽可能靠近它的顶点。首先检查离第一个顶点最近的层,逐渐向下移动到离第一个节点最远的层。
广度搜索使用抽象队列而不是数组对已访问过的顶点进行排序。

Map.prototype.bfs = function (s) {
  let quenen = [];
    this.marked[s] = true;
    quenen.push(s);
    while(quenen.length > 0){
        let v = quenen.shift();
        if(v === undefined){
            console.log(v+'undefined');
        }       
        for(let i in this.adj[v]){
            if(!this.marked[i]){
               this.edgeTo[i] = v;
               this.marked[i] = true;
               quenen.push(i);
            }
        }
    }
}
原理

查找与当前顶点相邻的未访问顶点,将其添加到已访问顶点列表及队列中。
从图中取出下一个顶点,添加到已访问的列表顶点。
将所有与V相邻的未访问顶点添加到队列。

查找最短路径

广度优先搜索最短路径

// bfs 函数
function bfs(s) {
    var queue = [];
    this.marked[s] = true;
    queue.push(s); //添加到队尾
    while (queue.length > 0) {
        var v = queue.shift(); //从队首移除
        if (v == undefined) {
            print("Visisted vertex:  " + v);
        }
        for each(var w in this.adj[v]) {
            if (!this.marked[w]) {
                this.edgeTo[w] = v;
                this.marked[w] = true;
                queue.push(w);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端御书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值