js数据结构和算法(四)图和图算法

图的定义

图(Graph)是由极点的有穷非空鸠合和极点之间边的鸠合组成,一般示意为:G(V,E),个中,G示意一个图,V是图G中极点的鸠合,E是图G中边的鸠合。

有向图

《js数据结构和算法(四)图和图算法》
有向边:若从极点ViVj的边有方向,则称这条边为有向边,也成为弧(Arc),用有序偶<Vi,Vj>来示意,Vi称为弧尾,Vj称为弧头。

无序图

**《js数据结构和算法(四)图和图算法》
无向边:**若极点ViVj之间的边没有方向,则称这条边为无向边(Edge),用无序偶(Vi,Vj)来示意。

简朴图

简朴图:在图构造中,若不存在极点到其本身的边,且统一条边不重复涌现,则称如许的图为简朴图。

图类

示意极点

建立图类的第一步就是要建立一个Vertex类来保留极点和边。这个类的作用和链表、二叉搜刮树的Node类一样。Vertex类有两个数据成员:一个用于标识极点,另一个表明是不是被接见过的布尔值。分别被命名为labelwasVisited

function Vertex(label){
    this.label = label;
}

我们将一切极点保留在数组中,在图类里,能够经由过程他们在数组中的位置援用他们

示意边

图的现实信息都保留在“边”上面,由于他们形貌了图的构造。二叉树的一个父节点只能有两个子节点,而图的构造却要天真很多,一个极点既能够有一条边,也能够有多条边和它相连。

我们将示意图的边的要领成为毗邻表或许毗邻表数组。它将存储由极点的相邻极点列表组成的数组

构建图

定义以下一个Graph类:

function Graph(v){
    this.vertices = v;//vertices至高点
    this.edges = 0;
    this.adj = [];
    for(var i =0;I<this.vertices;++i){
        this.adj[i] = [];
        this.adj[i].push('');
    }
    this.addEdge = addEdge;
    this.toString = toString;
}

这个类会纪录一个图示意了若干条边,并运用一个长度与图的极点数来纪录极点的数目。

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

这里我们运用for轮回为数组中的每一个元素增加一个子数组来存储一切的相邻极点,并将一切元素初始化为空字符串。

图的遍历

深度优先遍历

深度优先遍历(DepthFirstSearch),也有称为深度优先搜刮,简称为DFS

比如在一个房间内寻觅一把钥匙,不管从哪一间房间最先都能够,将房间内的墙角、床头柜、床上、床下、衣柜、电视柜等挨个寻觅,做到不放过任何一个死角,当一切的抽屉、储藏柜中全部都找遍后,接着再寻觅下一个房间。

深度优先搜刮:
《js数据结构和算法(四)图和图算法》
深度优先搜刮就是接见一个没有接见过的极点,将他标记为已接见,再递归地去接见在初始极点的毗邻表中其他没有接见过的极点

为Graph类增加一个数组:

this.marked = [];//保留已接见过的极点
for(var i=0;i<this.vertices;++i){
    this.marked[i] = false;//初始化为false
}

深度优先搜刮函数:

function dfs(v){
    this.marked[v] = true;
    //if语句在这里不是必需的
    if(this.adj[v] != undefined){
        print("Visited vertex: " + v );
        for each(var w in this.adj[v]){
            if(!this.marked[w]){
                this.dfs(w);
            }
        }
    }
}

广度优先搜刮

广度优先搜刮(BFS)属于一种自觉征采法,目标是体系地睁开并搜检图中的一切节点,以找寻效果。换句话说,它并不斟酌效果的能够位置,彻底地搜刮整张图,直到找到效果为止。

广度优先搜刮从第一个极点最先,尝试接见尽量接近它的极点,以下图所示:

《js数据结构和算法(四)图和图算法》

其事情道理为:

 1. 起首查找与当前极点相邻的未接见的极点,将其增加到已接见极点列表及行列中;
 2. 然后从图中掏出下一个极点v,增加到已接见的极点列表
 3. 末了将一切与v相邻的未接见极点增加到行列中

下面是广度优先搜刮函数的定义:

function bfs(s){
    var queue = [];
    this.marked = true;
    queue.push(s);//增加到队尾
    while(queue.length>0){
        var v = queue.shift();//从队首移除
        if(v == undefined){
            print("Visited 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);
            }
        }
    }
}

《js数据结构和算法(四)图和图算法》

最短途径

在实行广度优先搜刮时,会自动查找从一个极点到另一个相连极点的最短途径

肯定途径

要查找最短途径,须要修正广度优先搜刮算法来纪录从一个极点到另一个极点的途径,我们须要一个数组来保留从一个极点操下一个极点的一切边,我们将这个数组命名为edgeTo

this.edgeTo = [];//将这行增加到Graph类中

//bfs函数
function bfs(s){
    var queue = [];
    this.marked = true;
    queue.push(s);//增加到队尾
    while(queue.length>0){
        var v = queue.shift();//从队首移除
        if(v == undefined){
            print("Visited 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);
            }
        }
    }
}

拓扑排序算法

拓扑排序会对有向图的一切极点举行排序,使有向边夙昔面的极点指向背面的极点。
拓扑排序算法与BFS相似,差别的是,拓扑排序算法不会马上输出已接见的极点,而是接见当前极点毗邻表中的一切相邻极点,直到这个列表穷尽时,才会将当前极点压入栈中。

拓扑排序算法被拆分为两个函数,第一个函数是topSort(),用来设置排序历程并挪用一个辅佐函数topSortHelper(),然后显现排序好的极点列表

拓扑排序算法重要事情是在递归函数topSortHelper()中完成的,这个函数会将当前极点标记为已接见,然后递归接见当前极点毗邻表中的每一个极点,标记这些极点为已接见。末了,将当前极点压入栈中。

//topSort()函数
function topSort(){
    var stack = [];
    var visited = [];
    for(var i =0;i<this.vertices;i++){
        visited[i] = false;
    }
    for(var i = 0;i<this.vertices;i++){
        if(visited[i] == false){
            this.topSortHelper(i,visited,stack);
        }
    }
    for(var i = 0;i<stack.length;i++){
        if(stack[i] !=undefined && stack[i] != false){
            print(this.vertexList[stack[i]]);
        }
    }
}

//topSortHelper()函数
function topSortHelper(v,visited,stack){
    visited[v] = true;
    for each(var w in this.adj[v]){
        if(!visited[w]){
            this.topSortHelper(visited[w],visited,stack);
        }
    }
    stack.push(v);
}





    原文作者:trigkit4
    原文地址: https://segmentfault.com/a/1190000002410553
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞