一、基本定义

图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。

1. 图的分类

图是按照无方向和有方向分为无向图和有向图。

图_第1张图片

左图为无向图是由顶点和边构成,右图为有向图是由顶点和弧(有向边构成)。弧有弧头和弧尾区别。

图_第2张图片

这种边带权值的图叫网。

2. 图的顶点和边间的关系

顶点的度:顶点关联边的数目。有向图图中有,入度:方向指向顶点的边;出度:方向背向顶点的边。在有向图中顶点的度就是两者之和。

路径长度:路径上边或者弧的数目。


二、 图的存储结构

图的结构比较复杂,任意两个顶点之间都可能存在关系,不能用简单的顺序存储结构来表示。如果运用多重链表,即一个数据域多个指针域组成的结点表示图中一个结点,则造成大量存储单元浪费。

1、邻接矩阵

邻接矩阵用两个数组保存数据。一个一维数组存储图中顶点信息,一个二维数组存储图中边或弧的信息。


图_第3张图片

无向图中二维数组是个对称矩阵。

特点:

1️⃣ 0表示无边,1表示有边
2️⃣ 顶点的度是行内数组之和
3️⃣ 求取顶点邻接点,将行内元素遍历下


有向图

有向图中讲究入度和出度,各行之和是出度,各列之和是入度。

带权的图叫网,用邻接矩阵表示为:

图_第4张图片

邻接矩阵对于边数相对顶点较少的图,就是对存储空间极大的浪费。

2. 邻接表

数组和链表相结合的存储方法为邻接表。

图中顶点用一个一维数组存储。
图中每个顶点Vi的所有邻接点构成一个线性表。


图_第5张图片


三、图的遍历

1. 深度优先搜索

  • 从一条路径开始知道最后一个顶点,然后回溯继续下一条路径,反复直到没有路径;
  • 查找与当前顶点相邻未访问的顶点,将其值输出,并在标记数组中将相应标号标记为true;
  • 依次重复;

图_第6张图片

显然,深度优先搜索是一个递归的过程。

2. 广度优先搜索

  • 首先检查最靠近第一个顶点的层,然后逐层搜索;
  • 查找与当前顶点相邻未访问的顶点;将其添加到已访问列表;
  • 这一层访问之后从图中取出下一个顶点,添加到以访问列表;
    继续;

图_第7张图片


四、 代码展示

无向图,邻接矩阵

function Graph (v) {
    this.vertices = v; //顶点个数
    this.edges = 0;  //边条数
    this.adj = [];

    for(var i = 0; i < this.vertices; ++i) {
        this.adj[i] = [];  //二维数组
    };

    //记录已经访问过的顶点
    this.marked = [];
    for(var i = 0;i < this.vertices;i++){
        this.marked[i] = false;
    };

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

    this.showGraph = function(){
    	for(var i =0;i < this.vertices;i++){
    		for(var j = 0;j < this.vertices;j++){
    			if(this.adj[i][j] != undefined){
    				console.log(i+"->"+this.adj[i][j])
    			}
    		}
    	}
    };

    //深度优先搜索
    this.dfs = function(v){
        this.marked[v] = true;
        if (this.adj[v] != undefined) {
            console.log("Visited vertex: " + v);
        }

        for(var i = 0;i 0){
            var v = queue.shift();
            if(v != undefined){
                console.log("已访问 :"+v);
            }

            for(var k in this.adj[v]){            
                var w = this.adj[v][k];
                if(!this.marked[w]){
                    this.marked[w] = true;
                    queue.push(w);
                }
            }
        }        
    }
}


 var obj = new Graph(5);
 obj.addEdge(0,1);
 obj.addEdge(0,2);
 obj.addEdge(1,3);
 obj.addEdge(2,4);
 obj.showGraph();

 console.log("------------")

 obj.bfs(0);

你可能感兴趣的:(basic)