1.图的相关术语
1.1.有一条边相连的顶点叫相邻顶点;
1.2.一个顶点的度就是该顶点的相邻顶点数;
1.3.路径指顶点组成的连续序列;
1.4.简单路径没有重复顶点;
1.5.有向图和无向图
2.图的表示
2.1.邻接矩阵
array[i][j] ===1代表i节点和j节点相邻,否则不相邻
2.2.邻接表
相当于把每个节点的相邻节点一一列举出来。
2.3.关联矩阵
形式和邻接矩阵一样,只是把邻接矩阵的直接维度换成对应的边,适用于边比顶点多的情况。
3.创建图类
接下来就采用邻接表的方式创建上面的图并且采用字典来表示:
3.1.创建字典类
//创建字典类function Dictionary(){ var items = {}; //set(key,value)向字典里添加新元素,这里主要用来添加边 this.set = function(key,value){ items[key] = value; } //has(key)如果存在就返回true,否则false this.has = function(key){ return key in items; } //get(key)通过key查找特定的数值并返回,这里主要用来查找顶点对应的边数组 this.get = function(key){ return this.has(key) ? items[key] : undefined; }}
3.2.创建图类
//创建图类Graph()function Graph(){ var vertices = []; //用来储存顶点 var adjList = new Dictionary(); //用来储存边 //创建initializeColor用来初始化各个顶点的颜色,为遍历过程中的标记做准备 var initializeColor = function(){ var color = []; for (var i=0; i'; var neighbors = adjList.get(vertices[i]); for(var j=0; j
3.3.创建实例
//创建实例var graph = new Graph();var myVertices = ['A','B','C','D','E','F','G','H','I'];//添加顶点for(var i=0; i
输出的结果为:
A->B C D
B->A E F
C->A G D
D->A C G H
E->B I
F->B
G->C D
H->D
I->E
4.图的遍历
4.1.广度优先遍历
采用队列的方式,先添加节点的先被探索;
采用三种颜色来反应节点的状态:
白色:还没被访问;
灰色:被访问但未被探索;
黑色:被访问且探索过;
思路:
首先搜索节点A,探索A节点的相邻节点B,C,D,把其加入队列中,再逐一出队列进行探索,从而实现广度遍历。
添加bfs方法
//广度优先遍历,在Graph()类中添加以下方法this.bfs = function(v, callback){ var color = initializeColor(); //初始化节点,都标记为白色 var queue = []; //创建队列用来节点的入队; queue.push(v); //访问的节点入队列 while(!queue.length==0){ //如果队列非空就执行以下 var u = queue.shift(); //节点出队列 var neighbors = adjList.get(u); //探索节点对应的边 color[u] = 'grey'; //把搜索过的节点变成灰色 for (var i=0; i
bfs输出结果
Visited vertex:AVisited vertex:BVisited vertex:CVisited vertex:DVisited vertex:EVisited vertex:FVisited vertex:GVisited vertex:HVisited vertex:I
使用BFS寻找最短路径
this.BFS = function(v){ var color = initializeColor(), queue = [], d = [], //用来储存从v到u的距离 pred = []; //用来储存节点的前溯点 queue.push(v); for(var i=0; i
创建BFS实例
//BFS实例var shortestPathA = graph.BFS(myVertices[0]);//需要输入头节点myVertices[0]//console.log(shortestPathA);//搜索路径BFSvar fromVertex = myVertices[0];for (var i=1; i
BFS输出结果
A-B
A-C
A-D
A-B-E
A-B-F
A-C-G
A-D-H
A-B-E-I
4.2.深度优先遍历
采用栈的方式,先添加节点的先被探索;
由递归实现。
思路:
从节点A开始,探索到A的相邻节点B,C,D压入栈中(这里的代码采用for循环,所以没有实质上的栈,但是用栈更容易理解),接着搜索B,探索到B的相邻节点E,F压入栈中,以此递归。
添加dfs方法
this.dfs = function(callback){ var color = initializeColor(); for (var i=0; i
创建dfs实例
graph.dfs(printNode);
dfs输出结果
Visited vertex:AVisited vertex:BVisited vertex:EVisited vertex:IVisited vertex:FVisited vertex:CVisited vertex:GVisited vertex:DVisited vertex:H