用邻接表表示图:
如下图所示的图:
用邻接表二维数组表示为:
adj[0] = [1,2,5,6];
adj[1] = [0,3,8,9];
adj[2] = [0,4];
adj[3] = [1];
adj[4] = [2];
adj[5] = [0,7];
adj[6] = [0];
adj[7] = [5];
adj[8] = [1];
adj[9] = [1]
构建图类:
function Graph(v){
this.vertices = v;//顶点数
this.edges = 0;//边数
this.adj = [];//数组this.adj用来存放每个每个顶点的临接表
this.visited = [];//深度度优先搜索的是否访问标志
this.visited_2 = [];// 广度优先搜索的是否访问标志
for (var i = 0; i < this.vertices; i++){
this.adj[i] = [];
this.visited.push(false);
this.visited_2.push(false);
}
}
Graph.prototype = {
//存放方法
}
添加边
addEdge: function(a, b){
// a、b为节点
this.adj[a].push(b);
this.adj[b].push(a);
this.edges ++;//把总边数增加1
}
显示整个表
showGraph: function(){
for (var i = 0; i < this.vertices; i ++){
console.log(i + '=>');
for (var j = 0; j < this.vertices; j ++){
if (this.adj[i][j]){
console.log(this.adj[i][j]);
}
}
}
}
深度优先搜索
利用递归的思想,访问一个没有访问过的顶点,将它标记为已经访问,再递归的去访问在初始顶点的邻接表中的其他没有访问的节点;
// 深度优先搜索
dfs: function(vertice){
this.visited[vertice] = true;
console.log(vertice);
for (var i = 0; i < this.adj[vertice].length; i++){
var curVertice = this.adj[vertice][i];
if (!this.visited[curVertice]){
this.dfs(curVertice);
}
}
}
广度优先搜索
广度优先搜索从第一个顶点开始,尝试访问尽可能靠近它的节点,有点类似树的层序遍历;
//广度优先搜索
bfs: function(vertice){
var that = this;
var queue = [];
queue.push(vertice);
this.visited_2[vertice] = true;
// 当队列不为空时,循环进行;
while (queue.length > 0){
var curVertice = queue.shift();
console.log(curVertice);
this.adj[curVertice].forEach(function(item){
if (!that.visited_2[item]){
that.visited_2[item] = true;
queue.push(item);
}
})
}
}
实例化图,并使用深度优先搜索、广度优先搜索
创建树,新建边
var graph = new Graph(10);
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(0, 5);
graph.addEdge(0, 6);
graph.addEdge(1, 3);
graph.addEdge(1, 8);
graph.addEdge(1, 9);
graph.addEdge(2, 4);
graph.addEdge(5, 7);
显示图的结构:(邻接表):
graph.showGraph();
深度优先搜索:
graph.dfs(0);
广度优先搜索
graph.bfs(0);
寻找两点间的最短路径
首先在原型对象中写入一个allDistance函数,出入一个节点为参数,返回这个节点到其他所有节点的无权距离,用数组表示;
//无权图的单源最短路径的算法
allDistance: function(vertice){
var distance = [];
// 初始化distance数组,用来存放所有的距离
for (var i = 0; i < this.vertices; i++){
distance.push(-1);
}
var that = this;
var queue = [];
queue.push(vertice);
distance[vertice] = 0;
// 当队列不为空时,循环进行;
while (queue.length > 0){
//从队列中弹出一个节点
var curVertice = queue.shift();
//遍历与当前节点相邻的所有节点
this.adj[curVertice].forEach(function(item){
// 如果item没有被访问过
if (distance[item] < 0){
distance[item] = distance[curVertice] + 1;
queue.push(item);
}
})
}
return distance;
}
然后定义一个minDistance函数:返回从v点到w点的距离:
minDistance: function(v, w){
//先求出v到所有节点的距离
var distance = this.allDistance(v);
return distance[w];
}
验证一下:
在前面那个图实例中,
console.log(graph.minDistance(3,7));//4
console.log(graph.minDistance(1,2));//2